如何用Bash将多个tar.gz文件合并为单个tar.gz文件?
合并多个tar.gz文件为单个重新压缩归档(无需全解压)
问题原因
你之前执行的命令只是将原.sql.tar.gz文件作为普通文件添加到新归档中,并没有提取内部的.sql文件重新压缩,因此无法实现压缩率提升的需求。
解决方案:管道流式处理(无临时解压文件)
可以通过管道将每个tar.gz的解压内容直接传入新归档的压缩流程,全程无需将.sql文件写入磁盘,节省空间。
方法一:单命令链式处理
tar -zcf all_dbbackups.tar.gz - < <(for file in "$HOME/dbbackups"/*.sql.tar.gz; do [ -f "$file" ] && tar -zxf "$file" -O; done)
核心逻辑:
- 遍历
$HOME/dbbackups下所有.sql.tar.gz文件 - 用
tar -zxf "$file" -O解压每个文件并输出到标准输出(不落地磁盘) - 将所有解压后的内容汇总,通过管道传给
tar -zcf创建并压缩为新的归档
方法二:分步处理(适合需要中途验证的场景)
如果担心链式命令出现问题,可以先合并为未压缩的tar,再压缩:
#!/bin/bash TARGET="all_dbbackups.tar.gz" TEMP_TAR="temp_merged.tar" # 清理可能存在的临时文件 rm -f "$TEMP_TAR" "$TARGET" # 逐个解压并追加到临时tar for file in "$HOME/dbbackups"/*.sql.tar.gz; do [ -f "$file" ] || continue echo "正在处理:$(basename "$file")" tar -zxf "$file" -O | tar -rf "$TEMP_TAR" - done # 压缩临时tar为最终归档 gzip "$TEMP_TAR" mv "$TEMP_TAR.gz" "$TARGET" echo "合并完成:$TARGET"
注意事项
- 如果多个源tar.gz中存在同名的.sql文件,后面的文件会覆盖前面的,执行前请确认文件名唯一性,或通过
tar --transform参数给文件添加前缀(比如来源文件名):# 示例:给每个.sql文件添加原压缩包的前缀 for file in "$HOME/dbbackups"/*.sql.tar.gz; do [ -f "$file" ] || continue prefix=$(basename "$file" .sql.tar.gz) tar -zxf "$file" --transform="s/^/$prefix_/" -O | tar -rf "$TEMP_TAR" - done - 确保系统有足够的管道缓冲区或内存,避免大文件处理时出现异常
内容的提问来源于stack exchange,提问作者pg0
相关产品推荐
相关产品推荐

