Як знати, скільки місця займе нестиснений блискавка


23

З огляду на (дійсно довгий) список zip-файлів, як можна визначити розмір їх одного разу нестисненого?

Відповіді:


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

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перелічує розмір кожного файлу та друкує заключний рядок із їх сумою. Таким чином, ви можете прокручувати поштові файли та додавати вихід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 на файл, оскільки це розмір inode (для XFS). Я думаю, що ext4 все ще статично виділяє вставки, однак, так що простір, який не використовується для inode, не міг би зберігати інші дані. (Ось чому ext4 має таку низьку кількість вільних inodes ( df -i), порівняно з XFS, яка може динамічно виділити стільки місця, скільки потрібно.)
Пітер Кордес,

1

Дивись ма, без петель!

Ось ще одне рішення, яке може бути дещо швидшим, оскільки воно не використовує циклів, але все ж приходить до тієї ж відповіді.

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

Частина "BEGIN {total = 0}" не обов'язково обов'язково.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.