Comment puis-je vérifier si un fichier compressé est vide?

10

Existe-t-il un moyen rapide de vérifier si un fichier compressé est vide, ou dois-je le décompresser en premier?

exemple:

$ 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
la source

Réponses:

8

gzip -l foo.gz | awk 'NR==2 {print $2}' imprime la taille des données non compressées.

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

Vous pouvez également commencer à décompresser les données.

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

(Si votre système n'a pas head -cà extraire le premier octet, utilisez head -n 1plutôt pour extraire la première ligne.)

Gilles 'SO- arrête d'être méchant'
la source
Je suppose LC_ALL=Cqu'il est là pour s'assurer que gzip ne met pas en milliers de séparateurs en nombre afin que le champ puisse être comparé à zéro?
camh
1
@camh: C'est une paranoïa plus générale lors de l'analyse d'une sortie formatée à partir d'une commande. Cela pourrait être le format numérique, ou que dans certaines langues, il y a deux lignes d'en-tête, ou bien d'autres choses auxquelles je n'ai tout simplement pas pensé. Dans le cas de gzip, je pense qu'il ne se passe rien de mal, mais je ne LC_ALL=Cpeux pas faire de mal.
Gilles 'SO- arrête d'être méchant'
1
La deuxième alternative échouera si le fichier contient des données mais n'a pas de nouvelle ligne; il n'imprimera pas non plus la ligne telle qu'elle readest invoquée dans un sous-shell (et $linen'est pas propagée au parent).
Chris Down
1
@ChrisDown Bien repéré. Cependant, votre correctif n'est pas suffisant (plus la façon dont vous l'avez écrit est uniquement bash). Si le fichier commence par un octet nul, le shell (autre que zsh) verra une chaîne vide alors qu'il ne devrait pas. Un tuyau à travers trrésout cela.
Gilles 'SO- arrête d'être méchant'
4

Si par «vide» vous voulez dire que le fichier non compressé fait 0 octet, vous pouvez utiliser gzip --list foo.gzpour déterminer la taille du fichier non compressé, cela nécessiterait une analyse syntaxique pour l'automatiser. Cela ressemble à ceci:

$ gzip --list foo.gz
         compressed        uncompressed  ratio uncompressed_name
                 24                   0   0.0% foo
jsbillings
la source
C'est essentiellement la réponse 1!
Henno Brandsma
1
... qui a été posté après celui-ci.
jsbillings
2
test -z $(gzip -cd foo.gz | head -c1) && echo "empty"

Ou avec if:

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

zcatest parfois lié à gunzip -cou gzip -cd, si vous voulez l'utiliser comme "forme" plus courte.

remuer
la source
0

Veuillez noter que le format de fichier gzip n'autorise que 32 bits pour stocker la taille du fichier d'origine, donc le nombre est la taille modulo 2 ^ 32. Par conséquent, la taille donnée par "gzip -l" n'est pas un test définitif de vide.

Brendan
la source
2
Veuillez en faire une réponse plus complète en incluant un exemple de la façon dont vous aborderiez une solution.
George M