多个GZip文件的快速连接

117

我有一组gzip文件:

file1.gz
file2.gz
file3.gz

有没有一种方法可以将这些文件连接或压缩成一个gzip文件,而无需对其进行解压缩

实际上,我们将在web数据库(CGI)中使用它。网页将从用户那里接收查询,根据查询列出所有文件,并将它们作为批处理文件呈现给用户。

4个回答

144

对于gzip文件,您可以简单地将文件串联起来,如下所示:

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

根据gzip RFC,gzip文件由一系列“成员”(压缩的数据集)组成。成员在文件中依次出现,它们之间没有额外的信息。请注意,这与构建连接数据的单个gzip文件并不完全相同;除其他外,所有原始文件名都被保留。然而,gunzip似乎将其处理为等效于串联。由于现有工具通常忽略附加成员的文件名标头,因此不容易从结果中提取单个文件。如果要实现这一点,请构建ZIP文件。ZIP和GZIP都使用DEFLATE算法进行实际压缩(ZIP还支持一些其他压缩算法,并提供一个选项-方法8对应于GZIP的压缩)。差异在于元数据格式。由于元数据是未压缩的,因此很容易剥离gzip标头,并附加ZIP文件标头和中央目录记录。请参阅gzip格式规范ZIP格式规范


46
没错,只需执行cat file1.gz file2.gz file3.gz > allfiles.gz即可。就是这么简单 :) - bdonlan
21
不必将一堆gz文件打包成zip,直接把它们打成tar包即可。这与使用“cat”命令的答案相同,只是多了一些元数据。你后来可以解压tar包以获取原始文件名,然后根据需要全部或部分地解压缩。 - sorpigal
2
这里有许多关于.zip文件的评论。使用gzip(或bzip2)算法将多个文件放在一起形成一个压缩归档文件的标准方法是使用tar:tar将文件组合在一起(未压缩),并保留文件名和属性,gzip的工作是压缩结果。这甚至可以使用tar-z选项一步完成。生成的文件扩展名为.tar.gz.tgz。如果您想将已经压缩的.gz文件放在一起,只需使用tar即可。它不会进行进一步的压缩,这对于已经压缩的文件是有意义的。 - Daniel Alder
3
@alvas,zcat会对输入进行解压缩,因此输出的文件将是一个以.gz为扩展名的已解压缩的文件。 - bdonlan
4
显然有些工具会在到达第一个压缩的成员结尾时错误地停止。https://github.com/pysam-developers/pysam/issues/738#issuecomment-487958180 - Jeremy Leipzig
显示剩余5条评论

58

以下是您要求的关于man 1 gzip的内容:

多个压缩文件可以被连接在一起。这种情况下,gunzip会一次性提取所有成员。例如:

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

那么

gunzip -c foo

等同于

cat file1 file2
毋庸置疑,file1 可以被替换为 file1.gz
你必须注意这一点:

gunzip 将一次性提取所有成员。

因此,如果要逐个获取所有成员,您将需要使用其他工具或编写代码以实现其功能。
但是,man页面中也有对此的解释。

如果您希望创建一个带有多个成员的单个归档文件,以便稍后可以独立提取成员,请使用诸如 tar 或 zip 的归档工具。 GNU tar 支持 -z 选项以透明地调用 gzip。gzip 被设计为 tar 的补充而非替代品。


21

只需使用cat命令。它非常快(对我来说,处理500 MB只需要0.2秒)

cat *gz > final
mv final final.gz
您可以使用zcat读取输出结果,以确保其易于查看:
zcat final.gz
我尝试了另一个答案中的'gz -c',但是当我使用已经被gzip压缩过的文件作为输入时得到的结果都是垃圾(我猜测它将其双重压缩了)。 PV: 更好的方法是,如果你有的话,使用'pv'而不是'cat':
pv *gz > final
mv final final.gz
这将为您提供一个进度条,展示它的工作进程,但它与cat命令执行的相同。

这将为您提供一个进度条,展示它的工作进程,但它与cat命令执行的相同。


1
这对我来说是最好的答案,因为我有许多被分成较小文件(即.gz.ae、.gz.ab)的.gz文件。所以,我只需执行“cat gz > final.gz”即可。 - zipline86
1
我担心 *gz 会把 final.gz 也捡起来,然后做一些奇怪的循环操作,但现在我知道它会在开头扩展 *gz 并将其转换为一个大命令。例如 cat a.gz b.gz c.gz ... > final.gz - 所以如果 final.gz 一开始不存在,它就不会被吸进去。 - matiu

11

您可以创建这些文件的tar文件,然后gzip tar文件以创建新的gzip文件。

tar -cvf newcombined.tar file1.gz file2.gz file3.gz
gzip newcombined.tar

9
为什么需要对新的tar文件进行gzip压缩呢?它已经被压缩了(除了tar元数据,应该很小)。 - thiton
2
你说得对。无论是否使用gzip,文件大小都不会有太大的差异,因为单个文件已经被gzip压缩了。只是因为他想要从这三个单独的文件中得到一个gzip文件。 - Drona
3
这句话的意思是:额外的gzip压缩对访问内容没有任何好处,反而会减慢速度。我认为原帖的要求实际上是生成一个单独文件的归档文件,而没有理由假定生成的文件应该是gzip文件。 - mc0e

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接