Comment savoir combien d'espace un zip non compressé prendra


23

Étant donné une liste (très longue) de fichiers zip, comment pouvez-vous déterminer leur taille une fois non compressés?

Réponses:


38

Vous pouvez le faire en utilisant unzip -Zt zipnamequi imprime un résumé directement sur le contenu de l'archive, avec la taille totale. Voici un exemple sur sa sortie:

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

Ensuite, en utilisant awk, vous pouvez extraire le nombre d'octets:

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

Enfin, mettez-le dans une boucle for comme dans la réponse de Tom:

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

19

Si vous tapez unzip -l <zipfile>, il imprime une liste de fichiers dans le zip, avec leurs tailles non compressées, puis la taille totale non compressée de tous.

Il s'agit d'une sortie lisible par l'homme, mais vous pouvez obtenir un nombre lisible par machine en utilisant unzip -l <zipfile> | tail -n1 | awk '{ print $1 }'.

Pour obtenir une taille totale:

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 -lrépertorie la taille de chaque fichier et imprime une dernière ligne avec leur somme. Vous pouvez donc parcourir les fichiers zip et additionner la sortie deunzip -l "$zip" | awk 'END {print $1}' ou de unzip -Zt "$zip" | awk 'END {print $3}'. Pour une boucle shell, unzip -Ztpeut être un peu plus rapide:

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

Cela vous indique uniquement la taille totale des fichiers. Chaque fichier a une petite surcharge: l'espace pour stocker son nom, l'espace pour stocker certaines de ses métadonnées, et éventuellement un peu d'espace inutilisé car la plupart des systèmes de fichiers allouent les fichiers en blocs. Sur les systèmes de fichiers typiques, la surcharge peut aller jusqu'à quelques kilo-octets. Ce n'est pas exactement prévisible car la surcharge dépend de la taille du fichier, de la structure du répertoire (à cause de la surcharge du répertoire) et des capacités du système de fichiers à fusionner plusieurs petits fichiers dans le même bloc.

Si la plupart des fichiers dépassent quelques kilo-octets, ne vous en faites pas. Mais si les fichiers sont très petits, vous voudrez peut-être prendre en compte les frais généraux. Encore une fois, la surcharge dépend du système de fichiers. Sur ext4, chaque fichier remplit un bloc complet (4 Ko par défaut sur la plupart des systèmes). Le script suivant rapproche la taille totale en arrondissant chaque fichier jusqu'à 4 Ko et en ajoutant la longueur du nom de fichier plus quelques octets.

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 pour avoir mentionné les petits fichiers et le fait que les systèmes de fichiers ne regroupent pas les petits fichiers comme le fait un zip. AFAIK, aucun système de fichiers traditionnel sur win / OSX / Linux / BSD (c'est-à-dire ceux que vous pourriez recommander à quelqu'un d'utiliser pour / et / home sur son bureau ou serveur) a un petit emballage de fichiers en option. Reiserfs avait une option pour faire ceci (et des queues de fichiers plus gros), mais ce n'est pas maintenu. Cependant, je n'avais pas pensé à des noms de fichiers massivement longs . Bonne prise.
Peter Cordes

Vous pouvez également ajouter une constante 256B ou 512B par fichier, car c'est la taille d'un inode (sur XFS). Je pense que ext4 alloue toujours statiquement les inodes, donc l'espace non utilisé pour les inodes ne peut pas contenir d'autres données de toute façon. (C'est pourquoi ext4 a un si petit nombre d'inodes libres ( df -i), par rapport à XFS qui peut allouer dynamiquement autant d'espace aux inodes qu'il en a besoin.)
Peter Cordes

1

Regardez ma, pas de boucles!

Voici une autre solution, qui peut être légèrement plus rapide, car elle n'utilise pas de boucles, mais arrive toujours à la même réponse.

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

La partie "BEGIN {total = 0}" n'est pas strictement requise.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.