Jak mogę sprawdzić, czy plik spakowany gzip jest pusty?

10

Czy istnieje szybki sposób sprawdzenia, czy plik spakowany gzipem jest pusty, czy najpierw muszę go rozpakować?

przykład:

$ 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
źródło

Odpowiedzi:

8

gzip -l foo.gz | awk 'NR==2 {print $2}' wypisuje rozmiar nieskompresowanych danych.

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

Alternatywnie możesz rozpocząć rozpakowywanie danych.

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

(Jeśli twój system nie musi head -cwyodrębnić pierwszego bajtu, użyj head -n 1zamiast niego , aby wyodrębnić pierwszy wiersz.)

Gilles „SO- przestań być zły”
źródło
Zakładam, LC_ALL=Cczy istnieje pewność, że gzip nie wstawi tysięcy separatorów w liczbach, aby pole można było porównać do zera?
camh
1
@camh: To bardziej ogólna paranoja podczas analizowania sformatowanych danych wyjściowych polecenia. Może to być format liczb, lub że w jakimś języku są dwie linie nagłówka lub wiele innych rzeczy, o których po prostu nie pomyślałem. W przypadku gzip myślę, że nic złego się nie dzieje, ale LC_ALL=Cnie może zranić.
Gilles „SO- przestań być zły”
1
Druga alternatywa zawiedzie, jeśli plik zawiera dane, ale nie ma nowej linii; nie wydrukuje również linii, ponieważ readjest wywoływana w podpowłoce (i $linenie jest propagowana do elementu nadrzędnego).
Chris Down,
1
@ChrisDown Dobrze zauważony. Twoja poprawka nie jest jednak wystarczająca (plus sposób, w jaki ją napisałeś, to tylko bash). Jeśli plik zaczyna się bajtem zerowym, powłoka (inna niż zsh) zobaczy pusty ciąg znaków, gdy nie powinna. Rura przez to trnaprawia.
Gilles „SO- przestań być zły”
4

Jeśli przez „pusty” rozumiesz, że nieskompresowany plik ma 0 bajtów, możesz użyć go gzip --list foo.gzdo określenia rozmiaru nieskompresowanego pliku, jego zautomatyzowanie wymagałoby parsowania. Wygląda to mniej więcej tak:

$ gzip --list foo.gz
         compressed        uncompressed  ratio uncompressed_name
                 24                   0   0.0% foo
jsbillings
źródło
To jest zasadniczo odpowiedź 1!
Henno Brandsma
1
... który został opublikowany po tym.
jsbillings
2
test -z $(gzip -cd foo.gz | head -c1) && echo "empty"

Lub z if:

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

zcatjest czasem powiązany z gunzip -club gzip -cd, jeśli chcesz użyć go jako krótszego „formularza”.

machać
źródło
0

Należy pamiętać, że format pliku gzip pozwala tylko na 32 bity do przechowywania oryginalnego rozmiaru pliku, więc liczba jest wielkości modulo 2 ^ 32. Dlatego rozmiar podany przez „gzip -l” nie jest ostatecznym testem na pustkę.

Brendan
źródło
2
Uczyń to bardziej kompletną odpowiedzią, podając przykład podejścia do rozwiązania.
George M,