¿Cómo puedo cambiar la primera línea de un gran file gzip sin descomprimirlo todo?

Actualmente tengo un file comprimido, A.gz que contiene muchos datos tabulados, incluido un encabezado en la primera línea. Quiero crear otro file, B.gz , que tenga los mismos datos que el file anterior, pero con un encabezado diferente.

La forma más sencilla de hacer esto sería descomprimir todos los A.gz , A.gz todo less la primera línea y volviendo a comprimir todo. Sin embargo, esto parece terriblemente ineficiente, especialmente porque la concatenación de dos files gzip -ed se descomprime correctamente en la concatenación de las versiones descomprimidas.

Me preguntaba si había una manera de hacer esto similar a esto:

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

Sin tener que descomprimir todo A.gz

Si solo quisiera insert otra línea en la parte superior, sería simple.

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

gzip permite la concatenación. Si no te importa informar un tamaño de file descomprimido si solo miras el file sin descomprimirlo, eso es. Además, algunos progtwigs no pueden manejar dichos files, WinRAR, por ejemplo.

Para estar más cerca de lo que realmente desea, la pregunta es si su file gzip está formado por bloques que funcionan de manera totalmente independiente entre sí y, de ser así, cómo encontrar el límite del bloque.

Si supiera que quería hacer esto de antemano y creó el gzip concatenando dos files gzip independientes en primer lugar, sería fácil de resolver; sin embargo, en files gzip arbitrarios, si se puede hacer, requerirá un conocimiento más profundo del formatting de file gzip.

Recuerdo que existía un progtwig así para bzip2 (pero olvidé su nombre), que creó un map de bloques bzip2 que le permitiría acceder directamente a compensaciones específicas sin descomprimir todo lo que venía antes.

En la línea de background, sin embargo, la mayoría de la gente simplemente recomprime. Probablemente no podrá evitar volver a escribir todo el file y escribir files suele ser más lento de lo que gzip puede comprimir datos, por lo que si lograra lograrlo, probablemente ahorrará algunos ciclos de CPU, pero no habrá time. .


No es una solución a su pregunta gzip , pero … no use la tail para deshacerse de la primera línea, es probable que sea muy ineficiente en comparación con un sed 1d o lo que sea. No es necesario contar todas las líneas de un file solo para deshacerse de la primera.

Qué tal si

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

Si NR (número de logging) es 1, imprima su propio encabezado. Deje todas las otras líneas intactas.

!!! ¡Esto es solo un pensamiento!

Puedes intentar y ejecutar

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

esto extraerá solo las primeras 100 líneas de los files comprimidos, y luego las volverá a comprimir y sobrescribirá finamente los mismos bloques en el file B.gz e.

el problema es que esa no es una solución real porque deberá asegurarse de que los datos ANTES y DESPUÉS consumen la misma cantidad de bytes, y luego ejecutar el file y calcular el CRC32 para el nuevo file y escribirlo en el file. pie de página del file.

Probablemente es mejor con la respuesta que steve te da.