cat直接合并大文件不可靠,因其无校验、无排序、无中断恢复:易因断电/磁盘满导致截断,通配符排序错乱(如access_10.log排前),混编码静默乱码,尾部二进制垃圾照收。

直接用 cat 合并大文本文件(几 GB 以上)极大概率出问题——不是命令不会执行,而是中途失败、内容错位、编码污染、顺序错乱这些隐患根本不会报错,只等你后续解析时才发现数据已损坏。
为什么 cat file1 file2 > all.log 在大文件场景下不可靠
它不校验、不排序、不反馈、不缓冲控制:
- cat 是纯流式复制,一旦中断(Ctrl+C、断电、磁盘满),目标文件就是截断脏数据,且无法断点续传
- 通配符如 cat *.log 依赖 ls 字典序,access_10.log 会排在 access_2.log 前面
- 不检查源文件编码,UTF-8 和 ISO-8859-1 混合时,cat 会静默输出乱码甚至截断行
- 不验证尾部完整性,某些日志轮转工具会在文件末尾写入 \0 或二进制垃圾,cat 照单全收
按自然序合并并带进度反馈的实操写法
核心是绕过 shell 通配符的不确定性,显式控制顺序和可观测性:
- 用 ls -v(version sort)确保 file_2.log 排在 file_10.log 前面
- 用 pv 显示实时吞吐和预估时间(需先 apt install pv 或 yum install pv)
- 所有错误必须捕获,不能让管道静默失败
示例命令:set -o pipefail; ls -v /data/logs/app_*.log | xargs -d '\n' cat | pv -s $(du -sb /data/logs/app_*.log | awk '{sum+=$1} END{print sum}') > merged.log
关键点:
- set -o pipefail 让任意管道阶段失败都触发整体退出
- xargs -d '\n' 防止文件名含空格或换行时崩坏
- pv -s 的总大小必须提前算准,否则进度条不准;du -sb 比 wc -c 更可靠(不受稀疏文件干扰)
真正稳的大文件合并:分块 + 校验 + 可断点
当文件超过 10GB 或对一致性要求极高(如审计日志、数据库导出),就得放弃单次流式拼接,改用可验证的分块流程:
- 先用 split 切成固定行数块(推荐 -l 500000,避免单块内存压力)
- 对每块运行 sha256sum 并保存到 chunks.sha256
- 拼接时用循环 + || 捕获失败位置,例如:for f in chunk_*.log; do cat "$f" >> final.log || { echo "FAIL: $f"; exit 1; }; done
- 合并完立刻抽样比对:diff ,别信 <code>wc -l
容易被忽略但致命的三件事:
- file -i file1.log file2.log 查编码是否混用
- tail -c 100 file1.log | od -c 看结尾有没有意外 \0
- df -h /target/mount 确保目标磁盘剩余空间 ≥ 所有源文件大小之和(cat 不做空间预检)


















