¿Cómo puedo verificar si un archivo comprimido está vacío?

10

¿Hay alguna forma rápida de verificar si un archivo comprimido está vacío, o tengo que descomprimirlo primero?

ejemplo:

$ touch foo
$ if [ -s foo ]; then echo not empty; fi
$ gzip foo
$ if [ -s foo.gz ]; then echo not empty; fi
not empty
$ wc -l foo.gz
      1 foo.gz
dogbane
fuente

Respuestas:

8

gzip -l foo.gz | awk 'NR==2 {print $2}' imprime el tamaño de los datos sin comprimir.

if LC_ALL=C gzip -l foo.gz | awk 'NR==2 {exit($2!=0)}'; then
  echo foo is empty
else
  echo foo is not empty
fi

Alternativamente, puede comenzar a descomprimir los datos.

if [ -n "$(gunzip <foo.gz | head -c 1 | tr '\0\n' __)" ]; then
    echo "foo is not empty"
else
    echo "foo is empty"
fi

(Si su sistema no tiene head -cque extraer el primer byte, use head -n 1para extraer la primera línea).

Gilles 'SO- deja de ser malvado'
fuente
Supongo LC_ALL=Cque existe para garantizar que gzip no ponga miles de separadores en números para que el campo se pueda comparar con cero.
camh
1
@camh: es una paranoia más general cuando se analiza la salida formateada de un comando. Podría ser el formato de número, o que en algún idioma hay dos líneas de encabezado, o muchas otras cosas que simplemente no he pensado. En el caso de gzip, creo que no pasa nada malo, pero LC_ALL=Cno puede hacer daño.
Gilles 'SO- deja de ser malvado'
1
La segunda alternativa fallará si el archivo tiene datos pero no tiene una nueva línea; tampoco imprimirá la línea como readse invoca en una subshell (y $lineno se propaga al padre).
Chris Down
1
@ChrisDown Bien visto. Sin embargo, su solución no es suficiente (además de la forma en que la escribió es solo bash). Si el archivo comienza con un byte nulo, el shell (que no sea zsh) verá una cadena vacía cuando no debería. Una tubería a través trarregla eso.
Gilles 'SO- deja de ser malvado'
4

Si por 'vacío' quiere decir que el archivo sin comprimir tiene 0 bytes, podría usarlo gzip --list foo.gzpara determinar el tamaño del archivo sin comprimir, requeriría algún análisis para automatizarlo. Se parece a esto:

$ gzip --list foo.gz
         compressed        uncompressed  ratio uncompressed_name
                 24                   0   0.0% foo
jsbillings
fuente
¡Esto es esencialmente la respuesta 1!
Henno Brandsma
1
... que fue publicado después de este.
jsbillings
2
test -z $(gzip -cd foo.gz | head -c1) && echo "empty"

O con if:

if [ -z $(gzip -cd foo.gz | head -c1) ]; then
  echo "empty"
fi

zcata veces está vinculado gunzip -cao gzip -cd, si desea usarlo como el "formulario" más corto.

meneo
fuente
0

Tenga en cuenta que el formato de archivo gzip solo permite 32 bits para almacenar el tamaño del archivo original, por lo que el número allí es el módulo de tamaño 2 ^ 32. Por lo tanto, el tamaño dado por "gzip -l" no es una prueba definitiva de vacío.

Brendan
fuente
2
Haga que esta sea una respuesta más completa al incluir un ejemplo de cómo abordaría una solución.
George M