Как узнать, сколько места займет несжатый почтовый индекс

23

Учитывая (действительно длинный) список zip-файлов, как вы можете определить их размер после распаковки?

Quora Feans
источник

Ответы:

38

Вы можете сделать это с помощью unzip -Zt zipnameраспечатки сводки непосредственно о содержимом архива с общим размером. Вот пример его вывода:

unzip -Zt a.zip
1 file, 14956 bytes uncompressed, 3524 bytes compressed:  76.4%

Затем, используя awk, вы можете извлечь количество байтов:

unzip -Zt a.zip | awk '{print $3}'
14956

Наконец, поместите его в цикл for, как в ответе Тома:

total=0
for file in *.zip; do # or whichever files you want
    (( total += $(unzip -Zt $file |awk '{ print $3 }') ))
done
echo $total
Bichoy
источник
19

Если вы unzip -l <zipfile>печатаете, он печатает список файлов внутри zip-файла с их несжатыми размерами, а затем общий несжатый размер всех из них.

Это удобочитаемый вывод, но вы можете получить машиночитаемый номер, используя unzip -l <zipfile> | tail -n1 | awk '{ print $1 }'.

Чтобы получить общий размер:

total=0
for file in *.zip; do # or whichever files you want
    (( total += $(unzip -l $file | tail -n1 | awk '{ print $1 }') ))
done
echo $total
Том Хант
источник
15

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}
'
Жиль "ТАК - перестань быть злым"
источник
+1 за упоминание маленьких файлов и тот факт, что файловые системы не упаковывают маленькие файлы вместе, как это делает zip. AFAIK, в win / OSX / Linux / BSD нет общепринятых файловых систем (то есть тех, которые вы могли бы порекомендовать кому-то использовать для / и / home на своем рабочем столе или сервере), в качестве опции есть небольшая упаковка файлов. Reiserfs имел возможность сделать это (и хвосты больших файлов), но он не поддерживается. Впрочем, я не думал о длинных именах файлов . Хороший улов.
Питер Кордес
Вы также можете добавить константу 256B или 512B на файл, так как это размер индекса (в XFS). Я думаю, что ext4 все еще статически распределяет иноды, поэтому пространство, не используемое для инодов, в любом случае не может содержать другие данные. (Вот почему ext4 имеет такое небольшое количество свободных inode ( df -i) по сравнению с XFS, которая может динамически выделять столько пространства для inode, сколько ему необходимо.)
Питер Кордес
1

Смотри, ма, петель нет!

Вот еще одно решение, которое может быть немного быстрее, потому что оно не использует циклы, но все же приходит к тому же ответу.

unzip -l \*.zip|awk 'BEGIN{total=0}/        [0-9]+ files/{total=total+$1;}END{print "total bytes: "total}'

Часть "BEGIN {total = 0}" строго не требуется.

WormFood
источник