Швидке об'єднання декількох файлів GZip


92

У мене є список файлів gzip:

file1.gz
file2.gz
file3.gz

Чи є спосіб об’єднати ці файли у стилі gzip в один файл gzip, не розпаковуючи їх?

На практиці ми будемо використовувати це у веб-базі даних (CGI). Де Інтернет отримає запит від користувача, перерахує всі файли на основі запиту та представить їх у пакетному файлі назад користувачеві.

Відповіді:


107

За допомогою файлів gzip ви можете просто об'єднати файли разом, наприклад:

cat file1.gz file2.gz file3.gz > allfiles.gz

Відповідно до gzip RFC ,

Файл gzip складається з ряду "членів" (стиснених наборів даних). [...] Учасники просто з’являються один за одним у файлі, без додаткової інформації перед ними, між ними або після них.

Зауважте, що це не зовсім те саме, що створити один файл gzip з об’єднаних даних; серед іншого, всі оригінальні назви файлів збережені. Однак, схоже, gunzip обробляє це як еквівалент конкатенації.

Оскільки існуючі інструменти зазвичай ігнорують заголовки імен файлів для додаткових членів, витягти окремі файли з результату непросто. Якщо ви хочете, щоб це стало можливим, натомість створіть файл ZIP. ZIP і GZIP обидва використовують алгоритм DEFLATE для фактичного стиснення (ZIP підтримує деякі інші алгоритми стиснення, а також опцію - метод 8 відповідає стисненню GZIP); різниця полягає у форматі метаданих. Оскільки метадані не стискаються, досить просто видалити заголовки gzip і замість них закріпити заголовки файлів ZIP та запис центральної директорії. Зверніться до специфікації формату gzip та специфікації формату ZIP .


41
Ні. Просто cat file1.gz file2.gz file3.gz > allfiles.gz. Це справді так просто :)
bdonlan

1
технічно кажучи, вони збережені. Просто існуючі інструменти, як правило, не мають можливості їх окремо витягувати. Можливо, вам захочеться розглянути побудову заголовка ZIP і каталогу - формат ZIP використовує той самий базовий алгоритм стиснення, тому справа лише в зміні (нестиснутих) метаданих. Погляньте на gzip.org/zlib/rfc-gzip.html (вихідний формат) та pkware.com/documents/casestudies/APPNOTE.TXT .
bdonlan

20
Краще, ніж створювати zip-файл із файлами gz, просто підсилюйте їх. Це те саме, що і catвідповідь, але з деякими додатковими метаданими. Пізніше можна зняти з них зоряну копію, щоб отримати оригінальні імена файлів, а потім розпакувати всі або лише декілька, якщо потрібно.
сорпігаль

1
багато коментарів тут стосуються .zipфайлів. Стандартним способом об'єднання декількох файлів в один стислий архів за допомогою алгоритму gzip (або bzip2) є використання tar: tarскладає файли (нестиснуті) та зберігає імена та атрибути файлів, завдання gzip - стиснути результат. це навіть можна зробити за один крок, використовуючи -zопцію tar. отримані розширення файлів є .tar.gzабо .tgz. Якщо ви хочете зібрати вже стислі файли .gz, просто використовуйте tar. він не виконує подальшого стиснення, що має сенс для вже стиснених файлів.
Даніель Олдер

2
@alvas, zcatрозпаковує свій вхід, так що ви отримаєте розпакований вивід із .gzрозширенням.
bdonlan

51

Ось що 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, а не як заміна.


13

Просто використовуйте кота. Це дуже швидко (0,2 секунди на 500 МБ для мене)

cat *gz > final
mv final final.gz

Потім ви можете прочитати висновок за допомогою zcat, щоб переконатися, що він гарний:

zcat final.gz

Я спробував іншу відповідь "gz -c", але у мене закінчилося сміття, коли я використовував уже gzipped-файли як вхідні дані (я думаю, це подвоїло їх стисло).

PV:

А ще краще, якщо у вас є, "pv" замість cat:

pv *gz > final
mv final final.gz

Це дає вам індикатор прогресу в процесі роботи, але робить те саме, що і кішка.


11

Ви можете створити файл tar з цих файлів, а потім gzip файл tar, щоб створити новий файл gzip

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

8
Чому саме ви повинні gzip новий файл tar? Він уже застібнутий (крім метаданих tar, які повинні бути невеликими).
Тітон

2
Ти правий. Не буде великої різниці у розмірі файлу, незалежно від того, чи спершу ви його створюєте, оскільки окремі файли вже зішпатовані. Це просто тому, що він хотів отримати файл gzip з трьох окремих файлів.
Дрона

1
Додатковий gzip просто уповільнює доступ до вмісту без жодної вигоди. Мені здається, що вимога OPs насправді полягає в тому, щоб результуючий архів був єдиним файлом, і немає підстав вважати, що результуючий файл повинен бути файлом gzip.
mc0e
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.