Concaténation rapide de plusieurs fichiers GZip

93

J'ai la liste des fichiers gzip:

file1.gz
file2.gz
file3.gz

Existe-t-il un moyen de concaténer ou de gzipper ces fichiers dans un seul fichier gzip sans avoir à les décompresser ?

En pratique, nous l'utiliserons dans une base de données Web (CGI). Où le Web recevra une requête de l'utilisateur et listera tous les fichiers basés sur la requête et les présentera dans un fichier batch à l'utilisateur.

Neversaint
la source

Réponses:

107

Avec les fichiers gzip, vous pouvez simplement concaténer les fichiers ensemble, comme ceci:

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

Selon le RFC gzip ,

Un fichier gzip se compose d'une série de "membres" (ensembles de données compressés). [...] Les membres apparaissent simplement les uns après les autres dans le fichier, sans informations supplémentaires avant, entre ou après eux.

Notez que ce n'est pas exactement la même chose que la construction d'un seul fichier gzip des données concaténées; entre autres, tous les noms de fichiers originaux sont conservés. Cependant, gunzip semble le traiter comme équivalent à une concaténation.

Étant donné que les outils existants ignorent généralement les en-têtes de nom de fichier pour les membres supplémentaires, il n'est pas facilement possible d'extraire des fichiers individuels du résultat. Si vous voulez que cela soit possible, créez un fichier ZIP à la place. ZIP et GZIP utilisent tous les deux l'algorithme DEFLATE pour la compression réelle (ZIP prend en charge d'autres algorithmes de compression ainsi qu'une option - la méthode 8 est celle qui correspond à la compression de GZIP); la différence réside dans le format des métadonnées. Étant donné que les métadonnées ne sont pas compressées, il est assez simple de supprimer les en-têtes gzip et de coller les en-têtes de fichiers ZIP et un enregistrement de répertoire central à la place. Reportez-vous à la spécification du format gzip et à la spécification du format ZIP .

bdonlan
la source
41
Nan. Juste cat file1.gz file2.gz file3.gz > allfiles.gz. C'est vraiment aussi simple que ça :)
bdonlan
1
techniquement parlant, ils sont préservés. C'est juste que les outils existants n'ont généralement pas la capacité de les extraire séparément. Vous voudrez peut-être vous pencher sur la création d'un en-tête et d'un répertoire ZIP - le format ZIP utilise le même algorithme de compression sous-jacent, il ne s'agit donc que de modifier les métadonnées (non compressées). Jetez un œil à gzip.org/zlib/rfc-gzip.html (le format source) et pkware.com/documents/casestudies/APPNOTE.TXT .
bdonlan
20
Mieux que créer un zip de fichiers gz, il suffit de les tarer. C'est la même chose que la catréponse mais avec quelques métadonnées supplémentaires. Vous pouvez ensuite les décompresser pour obtenir les noms de fichiers d'origine, puis décompresser tout ou juste quelques-uns selon vos besoins.
sorpigal
2
@alvas, zcatdécompresse son entrée, ce qui vous donnera une sortie décompressée avec une .gzextension.
bdonlan
2
Apparemment, certains outils s'arrêteront par erreur lorsqu'ils atteindront la fin du premier membre gzipé. github.com/pysam-developers/pysam/issues/…
Jeremy Leipzig
51

Voici ce que man 1 gzipdit votre exigence.

Plusieurs fichiers compressés peuvent être concaténés. Dans ce cas, gunzip extraira tous les membres à la fois. Par exemple:

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

ensuite

gunzip -c foo

est équivalent à

cat file1 file2

Inutile de dire, file1peut être remplacé par file1.gz.

Vous devez remarquer ceci:

gunzip extraira tous les membres à la fois

Donc, pour obtenir tous les membres individuellement, vous devrez utiliser quelque chose de supplémentaire ou écrire, si vous le souhaitez.

Cependant, ceci est également traité dans la page de manuel.

Si vous souhaitez créer un fichier d'archive unique avec plusieurs membres afin que les membres puissent ultérieurement être extraits indépendamment, utilisez un archiveur tel que tar ou zip. GNU tar prend en charge l' -zoption d'invoquer gzip de manière transparente. gzip est conçu comme un complément à tar, pas comme un remplacement.

Nehal Dattani
la source
13

Utilisez simplement un chat. C'est très rapide (0,2 seconde pour 500 Mo pour moi)

cat *gz > final
mv final final.gz

Vous pouvez ensuite lire la sortie avec zcat pour vous assurer qu'elle est jolie:

zcat final.gz

J'ai essayé l'autre réponse de «gz -c» mais je me suis retrouvé avec des déchets en utilisant des fichiers déjà gzippés en entrée (je suppose que cela les a compressés deux fois).

PV:

Mieux encore, si vous l'avez, 'pv' au lieu de chat:

pv *gz > final
mv final final.gz

Cela vous donne une barre de progression car cela fonctionne, mais fait la même chose que cat.

matiu
la source
11

Vous pouvez créer un fichier tar de ces fichiers, puis gzip le fichier tar pour créer le nouveau fichier gzip

tar -cvf newcombined.tar file1.gz file2.gz file3.gz
gzip newcombined.tar
Drone
la source
8
Pourquoi exactement devriez-vous gzip le nouveau fichier tar? Il est déjà compressé (à part les métadonnées de tar, qui devraient être petites).
thiton
2
Tu as raison. Il n'y aurait pas beaucoup de différence dans la taille du fichier, que vous le gzipiez ou non, car les fichiers individuels sont déjà gzip. C'est juste parce qu'il voulait avoir un fichier gzip parmi les trois fichiers individuels.
Drona
1
Le gzip supplémentaire ralentit simplement l'accès au contenu sans gain. Il me semble que l'exigence des OP est vraiment que l'archive résultante soit un fichier unique, et il n'y a aucune raison de supposer que le fichier résultant devrait être un fichier gzip.
mc0e