unzip -l
перечисляет размер каждого файла и выводит последнюю строку с их суммой. Таким образом, вы можете просмотреть zip-файлы в цикле и сложить вывод unzip -l "$ zip" | awk 'END {print $ 1}'
или unzip -Zt "$ zip" | awk 'END {print $ 3}'
. Для цикла оболочки unzip -Zt
может быть немного быстрее:
total=0
for z in *.zip; do
set $(unzip -Zt -- "$z")
total=$((total + $3))
done
Это только сообщает вам общий размер файлов. У каждого файла есть небольшие накладные расходы: пространство для хранения его имени, пространство для хранения некоторых его метаданных и, возможно, немного неиспользуемого пространства, потому что большинство файловых систем выделяют файлы блоками. В типичных файловых системах накладные расходы могут достигать нескольких килобайт. Это не совсем предсказуемо, потому что накладные расходы зависят от размера файла, от структуры каталогов (из-за накладных расходов на каталог) и от возможностей файловой системы по объединению нескольких небольших файлов в один блок.
Если размер большинства файлов превышает несколько килобайт, не беспокойтесь об этом. Но если файлы очень маленькие, вы можете принять во внимание накладные расходы. Еще раз, накладные расходы зависят от файловой системы. В ext4 каждый файл заполняет полный блок (4 КБ по умолчанию в большинстве систем). Следующий сценарий приближает общий размер, округляя каждый файл до 4 КБ и добавляя длину имени файла плюс несколько байтов.
for z in *.zip; do
unzip -l -- "$z"
done | awk '
$2 ~ /^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$/ {total += ($1+4095)/4096*4096 + length($0)}
END {print total}
'
El formato legible humano -de los números interfiere, por lo que primero debe tener una salida consistente. Portable, puede usar la opción -P
para generar en bloques de 1024
df -P | awk 'NR>2{sum+=$2}END{print sum}'
Si usa GNU df
puede especificar --blocksize
opción:
df --block-size=1 | awk 'NR>2{sum+=$2}END{print sum}'
NR>2
es para evitar tener que lidiar con la línea de encabezado Size
. En cuanto a volver a formatear los datos en un formato legible por humanos, si está en Linux puede usar la herramienta numfmt
; de lo contrario, -implemente el convertidor en awk
. Consulte la respuesta relacionada .
Tenga en cuenta también que df
genera tamaños para todos los sistemas de archivos, incluidos los sistemas de archivos virtuales como udev
y tmpfs
. Puede considerar filtrarlos si solo desea los discos físicos reales. Entonces, si consideramos solo los sistemas de archivos que tienen un archivo de dispositivo representado en el sistema de archivos /dev/
, probablemente podría usar algo como esto:
df -P | awk 'NR>2 && /^\/dev\//{sum+=$2}END{print sum}'
Con GNU df
, también podría considerar usar el indicador --local
para ignorar la eliminación de sistemas de archivos.
GNU df
puede hacer el total por sí mismo, y las versiones recientes (al menos desde 8.21, no estoy seguro acerca de las versiones anteriores )le permiten seleccionar los campos para generar, así que:
$ df -h --output=size --total
Size
971M
200M
18G
997M
5.0M
997M
82M
84M
84M
200M
22G
$ df -h --output=size --total | awk 'END {print $1}'
22G
deman df
:
--output[=FIELD_LIST]
use the output format defined by FIELD_LIST, or print all fields
if FIELD_LIST is omitted.
--total
elide all entries insignificant to available space, and produce
a grand total
В некоторых случаях (т.е. btrfs )файловая система появляется несколько раз в df. Так что лучшим решением будет
df | awk '/dev\/sd/ {sums[$1]=$3} END {for (i in sums) tot += sums[i]; print tot}' | numfmt --to=iec