Как я могу проверить, пустой ли файл gzipped?

10

Есть ли быстрый способ проверить, является ли файл gzip пустым, или я должен сначала распаковать его?

пример:

$ 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
кендырь
источник

Ответы:

8

gzip -l foo.gz | awk 'NR==2 {print $2}' печатает размер несжатых данных.

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

В качестве альтернативы вы можете начать распаковку данных.

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

(Если вашей системе не нужно head -cизвлекать первый байт, используйте head -n 1вместо этого для извлечения первую строку.)

Жиль "ТАК - перестань быть злым"
источник
Я предполагаю, LC_ALL=Cчто gzip не помещает тысячи разделителей в числа, чтобы поле можно было сравнить с нулем?
Camh
1
@camh: это более общая паранойя при разборе форматированного вывода команды. Это может быть формат чисел, или что в каком-то языке есть две строки заголовка, или многие другие вещи, о которых я просто не думал. В случае с gzip, я думаю, ничего плохого не случится, но LC_ALL=Cне повредит.
Жиль "ТАК - перестань быть злым"
1
Второй вариант потерпит неудачу, если в файле есть данные, но нет перевода строки; он также не будет печатать строку, readкоторая вызывается в подоболочке (и $lineне распространяется на родительский объект ).
Крис Даун
1
@ChrisDown Хорошо заметили. Однако вашего исправления недостаточно (плюс способ, которым вы написали, предназначен только для bash). Если файл начинается с нулевого байта, оболочка (кроме zsh) увидит пустую строку, когда не должна. Труба через это trисправляет.
Жиль "ТАК - перестать быть злым"
4

Если под «пустым» вы подразумеваете, что несжатый файл имеет gzip --list foo.gzразмер 0 байт, вы можете использовать его для определения размера несжатого файла, для его автоматизации потребуется некоторый анализ. Это выглядит примерно так:

$ gzip --list foo.gz
         compressed        uncompressed  ratio uncompressed_name
                 24                   0   0.0% foo
jsbillings
источник
Это по сути ответ 1!
Хенно Брандсма
1
... который был опубликован после этого.
Jsbillings
2
test -z $(gzip -cd foo.gz | head -c1) && echo "empty"

Или с if:

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

zcatиногда связано с gunzip -cили gzip -cd, если вы хотите использовать его в качестве более короткой «формы».

шутник
источник
0

Обратите внимание, что формат файла gzip позволяет хранить только 32 бита для хранения исходного размера файла, поэтому число там равно модулю 2 ^ 32. Следовательно, размер, указанный в «gzip -l», не является окончательным тестом на пустоту.

Brendan
источник
2
Пожалуйста, сделайте этот ответ более полным, включив пример того, как вы подходите к решению.
Джордж М