Jak wiedzieć, ile miejsca zajmie nieskompresowany zamek błyskawiczny

23

Biorąc pod uwagę (naprawdę długą) listę plików zip, w jaki sposób możesz określić ich rozmiar po rozpakowaniu?

Quora Feans
źródło

Odpowiedzi:

38

Możesz to zrobić za pomocą, unzip -Zt zipnamektóry drukuje podsumowanie bezpośrednio na temat zawartości archiwum, o całkowitym rozmiarze. Oto przykład jego wyjścia:

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

Następnie za pomocą awk możesz wyodrębnić liczbę bajtów:

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

Na koniec umieść go w pętli for, jak w odpowiedzi Toma:

total=0
for file in *.zip; do # or whichever files you want
    (( total += $(unzip -Zt $file |awk '{ print $3 }') ))
done
echo $total
Bichoj
źródło
19

Jeśli wpiszesz unzip -l <zipfile>, drukuje listę plików w zipie, z ich nieskompresowanymi rozmiarami, a następnie całkowitym rozmiarem wszystkich plików.

Jest to wyjście czytelne dla człowieka, ale można uzyskać numer do odczytu maszynowego za pomocą unzip -l <zipfile> | tail -n1 | awk '{ print $1 }'.

Aby uzyskać całkowity rozmiar:

total=0
for file in *.zip; do # or whichever files you want
    (( total += $(unzip -l $file | tail -n1 | awk '{ print $1 }') ))
done
echo $total
Tom Hunt
źródło
15

unzip -lwyświetla rozmiar każdego pliku i drukuje ostatni wiersz z ich sumą. Możesz więc przeglądać pliki zip i sumować dane wyjściowe zunzip -l "$zip" | awk 'END {print $1}' lub z unzip -Zt "$zip" | awk 'END {print $3}'. W przypadku pętli powłoki unzip -Ztmoże być nieco szybsza:

total=0
for z in *.zip; do
  set $(unzip -Zt -- "$z")
  total=$((total + $3))
done

To pokazuje tylko całkowity rozmiar plików. Każdy plik ma niewielki narzut: miejsce do przechowywania jego nazwy, miejsce do przechowywania niektórych metadanych i być może trochę nieużywanego miejsca, ponieważ większość systemów plików przydziela pliki w blokach. W typowych systemach plików obciążenie może wynosić nawet kilka kilobajtów. Nie jest to dokładnie przewidywalne, ponieważ narzut zależy od rozmiaru pliku, struktury katalogu (z powodu narzutu katalogu) i możliwości systemu plików w zakresie łączenia wielu małych plików w tym samym bloku.

Jeśli większość plików ma więcej niż kilka kilobajtów, nie przejmuj się tym. Ale jeśli pliki są bardzo małe, warto wziąć pod uwagę koszty ogólne. Ponownie narzut zależy od systemu plików. W ext4 każdy plik wypełnia pełny blok (domyślnie 4kB w większości systemów). Poniższy skrypt przybliża całkowity rozmiar, zaokrąglając każdy plik do 4kB i dodając długość nazwy pliku plus kilka bajtów.

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}
'
Gilles „SO- przestań być zły”
źródło
+1 za wzmiankę o małych plikach i fakt, że systemy plików nie pakują razem małych plików, tak jak zip. AFAIK, brak systemów plików głównego nurtu w systemach win / OSX / Linux / BSD (tj. Takich, które można polecić komuś używającemu systemu / i / home na swoim komputerze stacjonarnym lub serwerze) ma opcję pakowania małych plików. Reiserfs miał taką opcję (i ogony większych plików), ale nie jest to obsługiwane. Jednak nie myślałem o długich nazwach plików . Dobry chwyt
Peter Cordes,
Możesz także dodać stałą 256B lub 512B na plik, ponieważ jest to rozmiar i-węzła (na XFS). Myślę, że ext4 wciąż statycznie przydziela i-węzły, więc przestrzeń nieużywana dla i-węzłów i tak nie mogła pomieścić innych danych. (Właśnie dlatego ext4 ma tak małą liczbę wolnych i-węzłów ( df -i), w porównaniu do XFS, który może dynamicznie przydzielać tyle miejsca, ile potrzebuje.)
Peter Cordes
1

Spójrz, nie ma pętli!

Oto inne rozwiązanie, które może być nieco szybsze, ponieważ nie używa pętli, ale wciąż dociera do tej samej odpowiedzi.

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

Część „BEGIN {total = 0}” nie jest ściśle wymagana.

WormFood
źródło