Быстрая конкатенация нескольких файлов GZip - PullRequest
76 голосов
/ 04 ноября 2011

У меня есть список файлов gzip:

file1.gz
file2.gz
file3.gz

Есть ли способ объединить или сжать эти файлы в один файл gzip без необходимости распаковывать их?

На практике мы будем использовать это в веб-базе данных (CGI). Где веб получит запрос от пользователя и перечислить все файлы на основе запроса и представить их в пакетном файле обратно к пользователю.

Ответы [ 4 ]

84 голосов
/ 04 ноября 2011

С помощью файлов gzip вы можете просто объединить файлы вместе. Согласно gzip RFC ,

GZIP-файл состоит из серии «членов» (сжатых наборов данных). [...] Участники просто появляются один за другим в файле, без дополнительной информации до, между или после них.

Обратите внимание, что это не то же самое, что создание единого gzip-файла из объединенных данных; среди прочего, все оригинальные имена файлов сохраняются. Тем не менее, gunzip, кажется, обрабатывает его как эквивалент конкатенации.

Поскольку существующие инструменты, как правило, игнорируют заголовки имен файлов для дополнительных элементов, извлечь отдельные файлы из результата нелегко. Если вы хотите, чтобы это было возможно, вместо этого создайте ZIP-файл. ZIP и GZIP оба используют алгоритм DEFLATE для фактического сжатия (ZIP поддерживает некоторые другие алгоритмы сжатия, а также опцию - метод 8 соответствует алгоритму сжатия GZIP); Разница заключается в формате метаданных. Поскольку метаданные несжатые, достаточно просто убрать заголовки gzip и вместо них прикрепить заголовки ZIP-файлов и запись центрального каталога. См. Спецификацию формата gzip и спецификацию формата ZIP .

46 голосов
/ 13 ноября 2011

Вот что man 1 gzip говорит о вашем требовании.

Несколько сжатых файлов могут быть объединены. В этом случае gunzip извлечет всех участников сразу. Например:

gzip -c file1  > foo.gz
gzip -c file2 >> foo.gz

Тогда

gunzip -c foo

эквивалентно

cat file1 file2

Излишне говорить, что file1 можно заменить на file1.gz.

Вы должны заметить это:

gunzip извлечет всех участников сразу

Таким образом, чтобы собрать всех участников по отдельности, вам придется использовать что-то дополнительное или написать, если вы хотите это сделать.

Однако, это также описано на странице руководства.

Если вы хотите создать один архивный файл с несколькими членами, чтобы впоследствии их можно было извлекать независимо, используйте архиватор, такой как tar или zip. GNU tar поддерживает опцию -z для прозрачного вызова gzip. gzip разработан как дополнение к tar, а не как замена.

12 голосов
/ 18 ноября 2016

Просто используйте кошку. Это очень быстро (0,2 секунды на 500 МБ для меня)

cat *gz > final
mv final final.gz

Затем вы можете прочитать вывод с помощью zcat, чтобы убедиться, что он хорош:

zcat final.gz

Я попробовал другой ответ 'gz -c', но у меня получился мусор, когда в качестве входных данных использовались уже сжатые gzip-файлы (я полагаю, они дважды сжали их).

PV:

Еще лучше, если он у вас есть, 'pv' вместо cat:

pv *gz > final
mv final final.gz

Это дает вам индикатор выполнения, как он работает, но делает то же самое, что и cat.

11 голосов
/ 06 ноября 2011

Вы можете создать tar-файл из этих файлов, а затем распаковать tar-файл gzip для создания нового gzip-файла

tar -cvf newcombined.tar file1.gz file2.gz file3.gz
gzip newcombined.tar
...