我目前有一个压缩文件,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.gz
e 上的相同块。
问题是,这不是真正的解决方案,因为您需要确保前和后data 消耗相同数量的字节,然后遍历该文件并计算CRC32
新文件的 并将其写入文件的页脚。
你可能会更好地回答史蒂夫给你。
答案4
仍然解压它,但对于大文件来说比 zcat 或 gzip 快得多:
pigz -dc new_header.txt.gz A.gz | sed '2d' | pigz > B.gz
只需在运行上述命令之前将新标头放入new_header.txt
(不带换行符)并对其进行 gzip 压缩即可。