Comment puis-je changer la première ligne d'un gros file gzip sans le décompresser?

J'ai actuellement un file compressé, A.gz qui contient beaucoup de données tabulées, y compris un en-tête dans la première ligne. Je veux créer un autre file, B.gz , qui a les mêmes données que le file précédent, mais avec un en-tête différent.

La façon simple de le faire serait de décompresser l'set de A.gz , d' A.gz tout sauf la première ligne, et de A.gz tout. Cependant, cela semble terriblement inefficace, notamment parce que la concaténation de deux files gzip décompresse correctement la concaténation des versions décompressées.

Je me demandais s'il y avait moyen de faire cela de la même façon:

 zcat A.gz | head -n 1 | process_header | gzip > B.gz cat A.gz | (remove compressed header) >> B.gz 

Sans avoir à décompresser tous les A.gz

    Si vous vouliez simplement insert une autre ligne sur le dessus, ce serait simple.

     echo some line | gzip > newfile.gz cat newfile.gz oldfile.gz > result.gz 

    gzip permet la concaténation. Si cela ne vous dérange pas de signaler un file non compressé incorrect si vous regardez le file sans le décompresser, c'est le cas. En outre, certains programmes ne peuvent pas gérer de tels files, WinRAR par exemple.

    Pour se rapprocher de ce que vous voulez réellement, la question est de savoir si votre file gzip est constitué de blocs fonctionnant entièrement indépendamment l'un de l'autre, et si c'est le cas, comment find la limite du bloc.

    Si vous saviez que vous vouliez faire cela auparavant et créé le gzip en concaténant deux files indépendants gzip en premier lieu, il serait facile de résoudre; cependant, sur des files arbitraires gzip, si cela peut être fait du tout, il faudrait une connaissance plus approfondie du format de file gzip.

    Je me souviens qu'il y avait un tel programme pour bzip2 (mais j'ai oublié son nom), il a créé une carte de bloc bzip2 qui vous permettrait d'accéder directement à des offsets spécifiques sans décompresser tout ce qui l'a précédé.

    Sur la ligne de fond, cependant, la plupart des gens recompriment simplement. Vous ne pourrez probablement pas éviter de réécrire le file en entier et écrire des files est généralement plus lent que gzip peut compresser des données, donc – si vous avez réussi à le retirer, vous économiserez probablement des cycles CPU, mais pas de time .


    Pas une solution à votre question gzip mais … ne pas utiliser la tail pour se débarrasser de la première ligne, c'est probablement très inefficace par rapport à un sed 1d ou peu importe. Pas besoin de countr toutes les lignes d'un file juste pour se débarrasser du premier.

    Que diriez-vous

     zcat A.gz | awk '{if(NR==1){print "myheader"}else{print $0}}' | gzip > B.gz 

    Si NR (numéro d'logging) est 1, affichez votre propre en-tête. Laissez toutes les autres lignes intactes.

    !!! C'est seulement une pensée !!!

    Vous pouvez essayer et courir

     zcat file | head -n100 > tempfile vim tempfile # edit the file header cat tempfile | gzip | dd of=B.gz conv=notrunc 

    cela va extraire seulement les 100 premières lignes des files compressés, puis les compresser de nouveau et finira par écraser les mêmes blocs sur le file B.gz e.

    le problème est qu'il ne s'agit pas d'une solution réelle car vous devez vous assurer que datatables BEFORE et AFTER consumnt la même quantité d'octets, puis exécutez le file et calculez le CRC32 pour le nouveau file et écrivez-le pied de page du file.

    Vous êtes probablement mieux avec la réponse que Steve vous donne.