如何从拼接的gzipped文件中提取单个原始文件?
拆分拼接后的多成员gzip文件
背景说明
我们可以通过拼接多个gzip文件生成一个有效的合并gzip文件:
gzip -c A > A.gz gzip -c B > B.gz cat A.gz B.gz > AB.gz
解压这个合并文件会得到A和B的内容合并结果:
cat A B > ab gzip -dc AB.gz > AB diff ab AB
但需求是单独恢复原始的A、B文件。gzip官方文档提到多成员归档的独立提取建议用tar或zip,但因特定原因无法使用tar。
直接用gzip命令的--name参数只能输出第一个成员的内容(以其原始文件名保存):
gzip -kdN AB.gz
Python解决方案
由于gzip命令行工具无法直接拆分多成员归档,可通过Python解析gzip文件结构,逐个提取每个成员:
import gzip import os def split_multi_gzip(input_path): with open(input_path, 'rb') as f_in: member_index = 0 while True: try: # 从当前位置读取一个gzip成员 with gzip.GzipFile(fileobj=f_in, mode='rb') as gz: # 优先使用原始文件名,无则用默认命名 original_name = gz.name or f"member_{member_index}.dat" # 写入提取出的文件 with open(original_name, 'wb') as f_out: f_out.write(gz.read()) print(f"已提取文件: {original_name}") member_index += 1 except EOFError: # 所有成员处理完成,退出循环 break if __name__ == "__main__": split_multi_gzip("AB.gz")
使用步骤
- 将上述代码保存为
split_gzip.py - 执行命令:
python split_gzip.py - 脚本会自动识别拼接gzip中的所有成员,按原始文件名(或默认规则)输出单独文件
原理说明
多成员gzip归档本质是多个独立gzip文件的拼接,每个成员都有专属的文件头(含原始文件名等元信息)和校验尾。Python的gzip.GzipFile会读取到单个成员末尾后自动停止,下次调用会从下一个成员的起始位置开始解析,因此可循环处理所有成员。
内容的提问来源于stack exchange,提问作者umläute
相关产品推荐
相关产品推荐

