如何更改大 gzip 文件的第一行而不解压全部文件?

如何更改大 gzip 文件的第一行而不解压全部文件?

我目前有一个压缩文件,A.gz其中包含大量表格数据,包括第一行中的标题。我想创建另一个文件 ,B.gz它具有与前一个文件相同的数据,但具有不同的标头。

执行此操作的简单方法是解压缩除第一行之外的所有A.gz, tail-ing 内容,然后重新压缩所有内容。然而,这看起来效率非常低,特别是因为两个 -ed 文件的串联可以gzip正确地解压缩为解压缩版本的串联。

我想知道是否有一种方法可以做到类似的事情:

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

无需解压所有A.gz.

答案1

如果你只是想在上面插入另一行,那就很简单了。

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

gzip 允许串联。如果你不介意它报告错误的未压缩文件大小,如果你只是查看文件而不解压缩它,那就是。另外,有些程序无法处理此类文件,例如 WinRAR。

为了更接近您真正想要的,问题是您的 gzip 文件是否由彼此完全独立运行的块组成,如果是,如何找到块边界。

如果您事先知道要执行此操作并通过连接两个独立的 gzip 文件来创建 gzip,那么解决起来很容易;然而,对于任意 gzip 文件,如果能够做到这一点,则需要对 gzip 文件格式有更深入的了解。

我记得有这样一个 bzip2 程序(但我忘记了它的名字),它创建了一个 bzip2 块映射,允许您直接访问特定的偏移量,而无需解压缩它之前的所有内容。

但归根结底,大多数人只是重新压缩。无论如何,您可能无法避免重写整个文件,并且写入文件通常比 gzip 压缩数据慢,因此 - 如果您设法成功,您可能会节省一些 CPU 周期,但没有时间。


不是您问题的解决方案gzip,但是...不要用来tail删除第一行,与 ased 1d或其他内容相比,它可能非常低效。不需要仅仅为了删除第一行而计算文件的所有行。

答案2

怎么样

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

如果 NR(记录号)为 1,则输出您自己的标头。保持所有其他线路完好无损。

答案3

!!!这只是一个想法!

你可以尝试运行

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

这将从压缩文件中仅提取前 100 行,然后重新压缩它们,并精细地覆盖文件B.gze 上的相同块。

问题是,这不是真正的解决方案,因为您需要确保data 消耗相同数量的字节,然后遍历该文件并计算CRC32新文件的 并将其写入文件的页脚。

你可能会更好地回答史蒂夫给你。

答案4

仍然解压它,但对于大文件来说比 zcat 或 gzip 快得多:

pigz -dc new_header.txt.gz A.gz | sed '2d' | pigz > B.gz

只需在运行上述命令之前将新标头放入new_header.txt(不带换行符)并对其进行 gzip 压缩即可。

相关内容