Como posso verificar se um arquivo compactado com gzip está vazio?

10

Existe uma maneira rápida de verificar se um arquivo compactado em gzip está vazio ou preciso descompactá-lo primeiro?

exemplo:

$ 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
fonte

Respostas:

8

gzip -l foo.gz | awk 'NR==2 {print $2}' imprime o tamanho dos dados não compactados.

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

Como alternativa, você pode começar a descompactar os dados.

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

(Se o seu sistema não precisar head -cextrair o primeiro byte, use head -n 1para extrair a primeira linha.)

Gilles 'SO- parar de ser mau'
fonte
Presumo LC_ALL=Cestá lá para garantir que gzip não põe em separadores de milhar nos números de modo que o campo pode ser comparado a zero?
Camh
1
@camh: É uma paranóia mais geral ao analisar a saída formatada de um comando. Pode ser o formato numérico ou, em algum idioma, existem duas linhas de cabeçalho, ou muitas outras coisas em que simplesmente não pensei. No caso do gzip, acho que nada de ruim acontece, mas LC_ALL=Cnão pode machucar.
Gilles 'SO- stop be evil'
1
A segunda alternativa falhará se o arquivo tiver dados, mas não tiver uma nova linha; também não imprimirá a linha como readestá sendo chamada em um subshell (e $linenão é propagada para o pai).
Chris Baixo
1
@ChrisDown Bem avistado. Porém, sua correção não é suficiente (além do modo como você a escreveu, é apenas para o bash). Se o arquivo iniciar com um byte nulo, o shell (que não seja o zsh) verá uma string vazia quando não deveria. Um cano trque conserta isso.
Gilles 'SO- stop be evil'
4

Se por 'vazio' você quer dizer que o arquivo descompactado é de 0 bytes, você pode usar gzip --list foo.gzpara determinar o tamanho do arquivo descompactado, seria necessária uma análise para automatizá-lo. Parece algo como isto:

$ gzip --list foo.gz
         compressed        uncompressed  ratio uncompressed_name
                 24                   0   0.0% foo
jsbillings
fonte
Esta é essencialmente a resposta 1!
Henno Brandsma
1
... que foi publicado após este.
Jsbillings
2
test -z $(gzip -cd foo.gz | head -c1) && echo "empty"

Ou com if:

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

zcatàs vezes está vinculado a gunzip -cou gzip -cd, se você deseja usá-lo como o "formulário" mais curto.

abanar
fonte
0

Observe que o formato do arquivo gzip permite apenas 32 bits para armazenar o tamanho do arquivo original, portanto, o número do módulo 2 é 32 ^. Portanto, o tamanho dado por "gzip -l" não é um teste definitivo para o vazio.

Brendan
fonte
2
Faça desta uma resposta mais completa, incluindo um exemplo de como você abordaria uma solução.
187 George M