如何提取.tar.gz内文件时避免重复解压压缩,保留gzip格式?
问题
我们的流水线会生成数百万个.tar.gz文件,每个文件内只包含一个文本文件。现在需要交付仅用gzip压缩、未打包成tar格式的文本文件。目前我用下面的命令实现:
tar xvf output-059a270d.tar.gz output-059a270d.txt && gzip output-059a270d.txt
但有没有办法利用tar/.gz格式的特性,跳过先解压再重新压缩的步骤?
回答
必须可以!你的.tar.gz是「单文件打包成tar + 整体gzip压缩」的结构,完全能跳过中间生成未压缩文本的步骤,直接一步转成单独的.gz文件,省空间又省时间。
给你几个实用的方法:
1. 最简管道实现(推荐)
直接让tar把提取的文本内容输出到控制台,再通过管道传给gzip写入目标文件:
tar xOf output-059a270d.tar.gz output-059a270d.txt | gzip > output-059a270d.txt.gz
- 关键参数
O(大写O):让tar不把文件写到磁盘,而是直接输出内容到标准输出 - 全程没有中间的未压缩文本文件,磁盘IO少了一大截,处理百万级文件时效率提升很明显
2. 拆分gzip解压步骤的写法(适合调试)
如果你想先确认tar包的内容,也可以把外层gzip的解压单独拆出来,逻辑更清晰:
zcat output-059a270d.tar.gz | tar xO -f - output-059a270d.txt | gzip > output-059a270d.txt.gz
和上面的方法效率差不多,只是把gzip解压的步骤用zcat单独做了,适合排查问题时用。
3. 批量处理脚本
既然你有上百万个文件,手动一个个敲肯定不行,整个批量处理的循环:
for tarfile in *.tar.gz; do # 从tar文件名里提取出对应的txt文件名 txt_filename="${tarfile%.tar.gz}.txt" # 一步转换 tar xOf "$tarfile" "$txt_filename" | gzip > "${tarfile%.tar.gz}.txt.gz" done
把这段脚本存成convert.sh,给执行权限后运行,就能自动处理当前目录下所有.tar.gz文件。
内容的提问来源于stack exchange,提问作者kojiro
相关产品推荐
相关产品推荐

