Linux comm 命令超详细教程|文件对比 / 交集 / 差集一站式搞定
Linux 学习资料 https://pan.baidu.com/s/1A6qqBk2ViE_Le2cQjSowkQ?pwd=7uz8
1. 命令简介
comm 命令用于逐行比较两个已排序的文件,并按照预设的列格式输出比较结果。它默认输出三列,分别显示:
仅出现在第一个文件中的行 仅出现在第二个文件中的行 两个文件中共同存在的行
该命令是 GNU coreutils 工具集的一部分,常用于文本处理、数据对比和集合运算(如求交集、差集)。
2. 语法格式
bash
运行
comm [OPTION]... FILE1 FILE2- FILE1, FILE2要比较的两个文件。如果某个文件为 -,则表示从标准输入(stdin)读取数据。
- OPTION可选参数,用于控制输出格式和比较行为。
3. 常用选项及说明
表格
| 选项 | 说明 |
|---|---|
| -1 | 不输出第一列(仅 FILE1 中存在的行)。 |
| -2 | 不输出第二列(仅 FILE2 中存在的行)。 |
| -3 | 不输出第三列(两个文件共有的行)。 |
| --check-order | 严格检查输入行是否已正确排序,如果未排序则报错退出。 |
| --nocheck-order | 不检查输入行的排序(默认行为)。即使文件未排序,也继续比较。 |
| --output-delimiter=STR | 使用指定字符串 STR 作为列之间的分隔符,代替默认的制表符(TAB)。 |
| --total | 额外增加一个第四列,显示每一行的类别统计总数。 |
| -z, --zero-terminated | 将行终止符设置为 NUL(空字符,\0),而不是默认的换行符(\n)。 |
| --help | 显示帮助信息并退出。 |
| --version | 显示版本信息并退出。 |
返回值:
- 0:成功执行。
- 非 0:执行过程中出现错误(如文件无法打开、排序检查失败等)。
4. 示例用法
示例文件准备
假设有两个文本文件:
aaa.txt 内容:
plaintext
aaa bbb ccc ddd eee 111 222bbb.txt 内容:
plaintext
bbb ccc aaa hhh ttt jjj4.1 基本比较(默认输出三列)
bash
运行
comm --nocheck-order aaa.txt bbb.txt输出:
plaintext
aaa bbb ccc ddd eee 111 222 hhh ttt jjj说明:
- 第一列(无前导空白):仅 aaa.txt 中有的行(aaa, ddd, eee, 111, 222)。
- 第二列(一个制表符缩进):仅 bbb.txt 中有的行(aaa, hhh, ttt, jjj)。
- 第三列(两个制表符缩进):两个文件共有的行(bbb, ccc)。
注意:此例文件未排序,结果可能混乱,强调了排序的重要性。
4.2 比较已排序的文件
由于 comm 要求输入文件已按字典序排序,通常需要先使用 sort 命令处理:
bash
运行
sort aaa.txt > aaa_sorted.txt sort bbb.txt > bbb_sorted.txt comm aaa_sorted.txt bbb_sorted.txt输出将更加清晰,相同内容会正确对齐。
4.3 求两个文件的交集(共同行)
隐藏第一列和第二列,只显示共有的行:
bash
运行
comm aaa_sorted.txt bbb_sorted.txt -1 -2输出:
plaintext
bbb ccc4.4 求差集
仅显示在 aaa.txt 中但不在 bbb.txt 中的行:
bash
运行
comm aaa_sorted.txt bbb_sorted.txt -2 -3输出:
plaintext
111 222 aaa ddd eee仅显示在 bbb.txt 中但不在 aaa.txt 中的行:
bash
运行
comm aaa_sorted.txt bbb_sorted.txt -1 -3输出:
plaintext
hhh jjj ttt4.5 使用自定义列分隔符
将默认的制表符分隔改为竖线 |:
bash
运行
comm --output-delimiter=' | ' aaa_sorted.txt bbb_sorted.txt输出列之间将以 | 分隔,提高可读性。
4.6 处理以 NUL 分隔的输入(如 find 输出)
与 find 命令结合,比较两个目录中的文件名列表:
bash
运行
find dir1 -type f -print0 | sort -z > list1.txt find dir2 -type f -print0 | sort -z > list2.txt comm -z list1.txt list2.txt-z 选项确保正确处理包含换行符的文件名。
5. 注意事项
- 输入必须排序: comm 命令的核心前提是两个输入文件必须已按字典序排序。如果文件未排序,比较结果将不可预测。建议始终先使用 sort 命令排序,或使用 --nocheck-order 跳过检查(但结果可能不准)。
- 列的顺序固定: 输出列的顺序是固定的:第一列 = 仅 FILE1,第二列 = 仅 FILE2,第三列 = 共有。通过 -1、-2、-3 选项可以隐藏对应列。
- 默认分隔符为 TAB: 默认情况下,列之间以一个制表符(TAB)分隔。可使用 --output-delimiter 自定义分隔符,这在需要进一步处理输出时很有用。
- 与 diff 的区别: comm 用于比较已排序的文件,输出格式为并排列;diff 用于比较可能未排序的文件,输出格式为更改指令(如添加、删除、修改)。根据需求选择合适的工具。
- 大文件处理: comm 使用基于行的比较算法,适合处理大型文本文件,但前提是内存足以容纳行数据。
获取更多帮助:
- 查看手册页:man comm
- 查看 info 文档:info coreutils 'comm invocation'
- 显示内置帮助:comm --help
通过灵活组合选项,comm 可以高效完成文本集合运算,是 Shell 脚本中常用的数据对比工具。