linux合并文本文件首选cat,需去重用awk ‘!seen[$0]++’,去空行加NF,跳过头尾用sed或head/tail,加行号或文件标识用awk的FILENAME/NR变量。

Linux 合并多个文本文件最直接的方法是用 cat,但实际场景中常需去重、去空行、加序号、跳过头部/尾部、按条件筛选——这时 sed 和 awk 就派上用场了。下面整理几类高频需求的实用写法,不讲原理,只给能立刻跑通的命令。
基础合并:cat 最常用也最可靠
把 file1.txt、file2.txt、file3.txt 顺序拼成 all.txt:
cat file1.txt file2.txt file3.txt > all.txt
合并当前目录下所有 .log 文件(按字母序):
cat *.log > merged.log
注意:通配符展开顺序依赖文件名排序,如需指定顺序,显式列出或用 find + sort 控制。
合并时去重且保持顺序:awk ‘!seen[$0]++’
多个文件内容有重复行,想合并后每行只保留首次出现的一次(原顺序不变):
awk ‘!seen[$0]++’ file1.txt file2.txt file3.txt > unique.txt
- 这个写法比 sort -u 更轻量,不改变原始行序
- 若要去除空白行再合并去重:awk ‘NF && !seen[$0]++’ *.txt
- 区分大小写;如需忽略大小写,改用 awk ‘NF && !seen[tolower($0)]++’
合并时跳过每文件的前 N 行或末 N 行
比如每个日志文件开头都有 3 行头信息,不想合并进去:
sed ‘1,3d’ file1.txt file2.txt | awk ‘NF’ > clean.log
如果要跳过每个文件的最后 2 行(适合去掉 footer):
for f in *.txt; do head -n -2 “$f”; done | awk ‘NF’ > no_footer.log
- head -n -2 表示除最后两行外全部输出
- awk ‘NF’ 过滤掉空行,比 grep ‘.’ 更稳妥(能处理纯空格行)
- 避免用 tail -n +4 直接处理多文件,它对每个文件独立计数但 cat 后会混在一起
合并并添加行号/文件标识:awk 实现灵活标记
想看出某行来自哪个文件,或加全局序号便于追踪:
awk ‘{print FILENAME “:” NR “: ” $0}’ file1.txt file2.txt > labeled.txt
只在每文件开头加个分隔线:
awk ‘FNR==1{print “n=== ” FILENAME ” ===”} {print}’ *.conf > full.conf
- FILENAME 是当前文件名,FNR 是当前文件内行号,NR 是总行号
- 想加全局连续行号:awk ‘{print NR “: ” $0}’ *.txt
- 合并时统一补前缀(如日志时间戳):awk ‘{print “[2024-06-15] ” $0}’ *.log
基本上就这些。cat 负责“搬”,sed 负责“剪裁”,awk 负责“标记+逻辑”。不用死记,遇到具体需求,先想清楚要删什么、留什么、标什么,再挑对应工具组合就行。