Concatenación rápida de varios archivos GZip

93

Tengo una lista de archivos gzip:

file1.gz
file2.gz
file3.gz

¿Hay alguna forma de concatenar o comprimir estos archivos en un archivo gzip sin tener que descomprimirlos ?

En la práctica, usaremos esto en una base de datos web (CGI). Donde la web recibirá una consulta del usuario y enumerará todos los archivos basados ​​en la consulta y los presentará en un archivo por lotes de nuevo al usuario.

nunca santo
fuente

Respuestas:

107

Con los archivos gzip, simplemente puede concatenar los archivos juntos, así:

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

Según el RFC de gzip ,

Un archivo gzip consta de una serie de "miembros" (conjuntos de datos comprimidos). [...] Los miembros simplemente aparecen uno tras otro en el archivo, sin información adicional antes, entre o después de ellos.

Tenga en cuenta que esto no es exactamente lo mismo que crear un solo archivo gzip de los datos concatenados; entre otras cosas, se conservan todos los nombres de archivo originales. Sin embargo, gunzip parece manejarlo como equivalente a una concatenación.

Dado que las herramientas existentes generalmente ignoran los encabezados de los nombres de archivo de los miembros adicionales, no es fácil extraer archivos individuales del resultado. Si desea que esto sea posible, cree un archivo ZIP en su lugar. ZIP y GZIP utilizan el algoritmo DEFLATE para la compresión real (ZIP admite algunos otros algoritmos de compresión, así como una opción; el método 8 es el que corresponde a la compresión de GZIP); la diferencia está en el formato de metadatos. Dado que los metadatos no están comprimidos, es bastante simple quitar los encabezados gzip y agregar encabezados de archivos ZIP y un registro de directorio central en su lugar. Consulte la especificación del formato gzip y la especificación del formato ZIP .

bdonlan
fuente
41
No Solo cat file1.gz file2.gz file3.gz > allfiles.gz. Realmente es así de simple :)
bdonlan
1
técnicamente hablando, se conservan. Es solo que las herramientas existentes generalmente no tienen la capacidad de extraerlas por separado. Es posible que desee considerar la construcción de un encabezado y un directorio ZIP: el formato ZIP utiliza el mismo algoritmo de compresión subyacente, por lo que es solo una cuestión de cambiar los metadatos (sin comprimir). Eche un vistazo a gzip.org/zlib/rfc-gzip.html (el formato fuente) y pkware.com/documents/casestudies/APPNOTE.TXT .
bdonlan
20
Mejor que crear un zip de archivos gz, solo tarlos. Es lo mismo que la catrespuesta pero con algunos metadatos adicionales. Luego puede descomprimirlos para obtener los nombres de archivo originales y luego descomprimir todos o solo algunos según sea necesario.
Sorigal
2
@alvas, zcatdescomprime su entrada, por lo que le daría una salida descomprimida con una .gzextensión.
bdonlan
2
Aparentemente, hay algunas herramientas que se detendrán por error cuando lleguen al final del primer miembro con gzip. github.com/pysam-developers/pysam/issues/…
Jeremy Leipzig
51

Esto es lo que man 1 gzipdice sobre su requerimiento.

Se pueden concatenar varios archivos comprimidos. En este caso, gunzip extraerá todos los miembros a la vez. Por ejemplo:

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

Entonces

gunzip -c foo

es equivalente a

cat file1 file2

No hace falta decir que file1se puede reemplazar por file1.gz.

Debes notar esto:

gunzip extraerá todos los miembros a la vez

Entonces, para obtener a todos los miembros individualmente, tendrá que usar algo adicional o escribir, si lo desea.

Sin embargo, esto también se aborda en la página de manual.

Si desea crear un solo archivo de almacenamiento con varios miembros para que los miembros puedan extraerse posteriormente de forma independiente, utilice un archivador como tar o zip. GNU tar admite la -zopción de invocar gzip de forma transparente. gzip está diseñado como un complemento de tar, no como un reemplazo.

Nehal Dattani
fuente
13

Solo usa cat. Es muy rápido (0.2 segundos por 500 MB para mí)

cat *gz > final
mv final final.gz

Luego puede leer la salida con zcat para asegurarse de que sea bonita:

zcat final.gz

Probé la otra respuesta de 'gz -c' pero terminé con basura cuando usé archivos ya comprimidos con gzip como entrada (supongo que los comprimió dos veces).

PV:

Mejor aún, si lo tiene, 'pv' en lugar de cat:

pv *gz > final
mv final final.gz

Esto le da una barra de progreso mientras funciona, pero hace lo mismo que cat.

matiu
fuente
11

Puede crear un archivo tar de estos archivos y luego gzip el archivo tar para crear el nuevo archivo gzip

tar -cvf newcombined.tar file1.gz file2.gz file3.gz
gzip newcombined.tar
Drona
fuente
8
¿Por qué exactamente debería gzip el nuevo archivo tar? Ya está comprimido (aparte de los metadatos de tar, que deberían ser pequeños).
thiton
2
Tienes razón. No habría mucha diferencia en el tamaño del archivo si lo pone en gzip o no porque los archivos individuales ya están en gzip. Es solo porque quería tener un archivo gzip de los tres archivos individuales.
Drona
1
El gzip adicional solo ralentiza el acceso al contenido sin ningún beneficio. Me parece que el requisito de OP es realmente que el archivo resultante sea un solo archivo, y no hay razón para suponer que el archivo resultante debería ser un archivo gzip.
mc0e