ambevar-dotfiles/.scripts/pacsize

184 lines
3.9 KiB
Plaintext
Raw Normal View History

#!/bin/sh
2013-12-24 13:24:58 +01:00
# pacsize -- display package sizes
#
# Copyright (C) 2014 Pierre Neidhardt <ambrevar@gmail.com>
2013-12-24 13:24:58 +01:00
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
readonly myname='pacsize'
readonly myver='4.1.2'
calc_total () {
2015-02-16 15:32:53 +01:00
awk 'BEGIN {
unit["B"] = 1/1024
unit["KiB"] = 1
unit["MiB"] = 1024
unit["GiB"] = 1048576
unit["TiB"] = 1073741824
unit["PiB"] = 1099511627776
unit["EiB"] = 1125899906842624
unit["ZiB"] = 1152921504606846976
unit["YiB"] = 1180591620717411303424
}
{
2015-09-26 15:46:09 +02:00
u=$1
gsub(/[[:digit:]]*/, "", u)
n=$1
gsub(/[[:alpha:]]*/, "", n)
total += unit[u]*n
print
}
END {
printf ("%7s KIB TOTAL\n", total)
}'
}
error () {
echo "$@" >&2
}
2014-03-06 11:28:52 +01:00
## Print size and name. We round to the lowest integer, this makes output
## lighter.
filter () {
awk -F ": " \
'$0 ~ "^Name" {
pkg = $2
}
$0 ~ "^Installed Size" {
split($2, a, " ")
2015-08-22 18:01:00 +02:00
printf ("%4d%-3s %s\n", a[1], a[2], pkg)
}'
}
remove_duplicates () {
awk '! table[$0]++'
}
usage () {
cat <<EOF
Usage: ${1##*/} [OPTIONS] PACKAGES
2013-12-24 11:29:49 +01:00
${1##*/} -a [OPTIONS]
Display the size of PACKAGES. Duplicates are removed if any. The local database
is queried first; if the package is not found, the sync database is then used
for lookup.
2013-12-24 13:24:58 +01:00
Options:
-a: Process all installed packages.
2013-06-25 22:56:10 +02:00
-h: Show this help.
-n: Sort output by name.
-s: Sort output by size.
2013-12-24 12:12:25 +01:00
-t: Print total.
2014-03-06 11:28:52 +01:00
-V: Show version information.
2013-06-25 22:56:10 +02:00
2013-12-24 13:24:58 +01:00
Examples:
$ ${1##*/} -ast
2014-01-22 18:54:03 +01:00
Convenient way to keep track of big packages.
2013-12-24 13:24:58 +01:00
$ ${1##*/} \$(pactree -ld1 linux)
2014-01-22 18:54:03 +01:00
Print the size of linux and all its direct dependencies.
2013-12-24 13:24:58 +01:00
$ ${1##*/} -st \$(pacman -Qdtq)
2013-12-24 13:24:58 +01:00
Print a grand total of orphan packages, and sort by size.
EOF
}
version () {
echo "$myname $myver"
echo 'Copyright (C) 2014 Pierre Neidhardt <ambrevar@gmail.com>'
}
2013-12-24 13:24:58 +01:00
opt_sort=false
opt_all=false
opt_total=false
2014-03-06 11:28:52 +01:00
while getopts ":ahnstV" opt; do
case $opt in
a)
opt_all=true ;;
h)
usage "$0"
exit ;;
n)
opt_sort="sort -k3" ;;
s)
opt_sort="sort -h" ;;
t)
opt_total="calc_total" ;;
V)
version "$0"
exit ;;
\?)
usage "$0"
exit 1 ;;
esac
done
shift $(($OPTIND - 1))
## All-packages mode.
## We use a dedicated algorithm which is much faster than per-package mode.
## Unfortunately there is no easy way to select packages with this method.
2013-12-24 13:24:58 +01:00
if $opt_all; then
2014-03-06 02:51:50 +01:00
DBPath="$(awk -F "=[ \t]*" '/^[ \t]*DBPath[ \t]*=/{gsub(/[ \t]*$/, "", $2); print $2}' /etc/pacman.conf 2>/dev/null)"
[ -z "$DBPath" ] && DBPath="/var/lib/pacman"
if [ ! -d "$DBPath/local/" ]; then
error "Could not find local database in $DBPath/local/."
exit 1
fi
2013-12-24 11:29:49 +01:00
awk 'BEGIN {
split("B KiB MiB GiB TiB PiB EiB ZiB YiB", unit)
}
2014-03-06 02:51:50 +01:00
$0 == "%NAME%" {
getline pkg
}
2014-03-06 02:51:50 +01:00
$0 == "%SIZE%" {
getline size
i = 1
while (size > 2048) {
size /= 1024
i++
}
2015-08-22 18:01:00 +02:00
printf ("%4d%-3s %s\n", size, unit[i], pkg)
2014-03-06 02:51:50 +01:00
}' "$DBPath"/local/*/desc | { $opt_sort || cat ;} | { $opt_total || cat ;}
exit
2013-12-24 11:29:49 +01:00
fi
## Per-package mode.
if [ $# -eq 0 ]; then
error "Missing argument."
usage "$0"
exit 1
fi
2014-03-06 02:51:50 +01:00
## Remove this check if integrated to pacman.
if ! command -v pacman >/dev/null 2>&1; then
error "'pacman' not found."
exit 1
2013-12-24 12:21:44 +01:00
fi
{
## If package is not found locally (-Q), we use the sync database (-S). We
## use LC_ALL=C to make sure pacman output is not localized.
buffer=$(LC_ALL=C pacman -Qi "$@" 2>&1 1>&3 3>&- | cut -f2 -d "'")
[ -n "$buffer" ] && LC_ALL=C pacman -Si $buffer
2014-03-06 02:51:50 +01:00
} 3>&1 | filter | { $opt_sort || remove_duplicates ;} | { $opt_total || cat ;}
2013-10-29 21:49:48 +01:00
# vim: set noet: