Cómo saber cuánto espacio ocupará un zip sin comprimir


23

Dada una lista (realmente larga) de archivos zip, ¿cómo puede saber el tamaño de ellos una vez descomprimidos?

Respuestas:


38

Puede hacerlo utilizando el unzip -Zt zipnameque imprime un resumen directamente sobre el contenido del archivo, con un tamaño total. Aquí hay un ejemplo en su salida:

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

Luego, usando awk, puede extraer el número de bytes:

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

Finalmente, póngalo en un bucle for como en la respuesta 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 escribe unzip -l <zipfile>, imprime una lista de archivos dentro del zip, con sus tamaños sin comprimir, luego el tamaño total sin comprimir de todos ellos.

Esta es una salida legible por humanos, pero puede obtener un número legible por máquina usando unzip -l <zipfile> | tail -n1 | awk '{ print $1 }'.

Para obtener un tamaño total:

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 -lenumera el tamaño de cada archivo e imprime una línea final con su suma. Para que pueda recorrer los archivos zip y sumar la salida deunzip -l "$zip" | awk 'END {print $1}' o de unzip -Zt "$zip" | awk 'END {print $3}'. Para un bucle de shell, unzip -Ztpuede ser un poco más rápido:

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

Eso solo te dice el tamaño total de los archivos. Cada archivo tiene una pequeña sobrecarga: el espacio para almacenar su nombre, el espacio para almacenar algunos de sus metadatos, y posiblemente un poco de espacio no utilizado porque la mayoría de los sistemas de archivos asignan archivos en bloques. En sistemas de archivos típicos, la sobrecarga puede ser de unos pocos kilobytes. No es exactamente predecible porque la sobrecarga depende del tamaño del archivo, de la estructura del directorio (debido a la sobrecarga del directorio) y de las capacidades del sistema de archivos para fusionar múltiples archivos pequeños en el mismo bloque.

Si la mayoría de los archivos tienen más de unos pocos kilobytes, no se preocupe por esto. Pero si los archivos son muy pequeños, es posible que desee tener en cuenta los gastos generales. Una vez más, la sobrecarga depende del sistema de archivos. En ext4, cada archivo llena un bloque completo (4kB por defecto en la mayoría de los sistemas). El siguiente script aproxima el tamaño total al redondear cada archivo hasta 4kB y agregar la longitud del nombre del archivo más unos pocos bytes.

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 por mencionar archivos pequeños y el hecho de que los sistemas de archivos no empaquetan archivos pequeños juntos como lo hace un zip. AFAIK, no hay sistemas de archivos convencionales en win / OSX / Linux / BSD (es decir, los que podría recomendar que alguien use para / y / home en su escritorio o servidor) tienen una opción para empaquetar archivos pequeños. Reiserfs tenía una opción para hacer esto (y colas de archivos más grandes), pero no se mantiene. Sin embargo, no había pensado en nombres de archivo masivamente largos . Buena atrapada.
Peter Cordes

También puede agregar 256B o 512B constantes por archivo, ya que ese es el tamaño de un inodo (en XFS). Sin embargo, creo que ext4 todavía asigna estáticamente inodos, por lo que el espacio no utilizado para inodos no podría contener otros datos de todos modos. (Esta es la razón por la cual ext4 tiene un número tan bajo de inodos libres ( df -i), en comparación con XFS que puede asignar dinámicamente tanto espacio a los inodos como sea necesario.)
Peter Cordes

1

Mira ma, no hay bucles!

Aquí hay otra solución, que puede ser un poco más rápida, porque no usa bucles, pero aún así llega a la misma respuesta.

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

La parte "BEGIN {total = 0}" no es estrictamente necesaria.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.