comm 是一个用于比较两个已排序文件的命令,它的名字来源于 "common"(共同的),它的主要功能是逐行比较两个文件,并输出三列结果:

- 仅在第一个文件中出现的行
- 仅在第二个文件中出现的行
- 两个文件中都出现的行(交集)
语法
comm [选项] 文件1 文件2
重要前提: comm 要求输入的两个文件都必须是已排序的,并且通常是按行首字符的 ASCII 码顺序排序的,如果文件未排序,输出结果将是无意义的。
选项
comm 命令的选项非常直观,它们控制着三列输出的显示方式,默认情况下,三列都会显示。
| 选项 | 全称 | 描述 |
|---|---|---|
-1 |
--suppress-column1 |
不显示第一列(仅在文件1中出现的行) |
-2 |
--suppress-column2 |
不显示第二列(仅在文件2中出现的行) |
-3 |
--suppress-column3 |
不显示第三列(两个文件共有的行) |
这些选项可以自由组合。-12 表示同时隐藏第一列和第二列,这样输出就只包含两个文件的交集了。
输出格式
comm 的默认输出格式是使用 Tab 键来分隔三列数据:

[仅在文件1中的行] [仅在文件2中的行] [共有的行]
- 如果某一行只在文件1中,那么第二列和第三列将是空的。
- 如果某一行只在文件2中,那么第一列和第三列将是空的。
- 如果某一行在两个文件中都存在,那么只有第三列会有内容。
实战示例
为了演示,我们先创建两个示例文件,并对它们进行排序。
# 创建文件1 echo "apple" > file1.txt echo "banana" >> file1.txt echo "orange" >> file1.txt echo "grape" >> file1.txt # 创建文件2 echo "banana" > file2.txt echo "kiwi" >> file2.txt echo "orange" >> file2.txt echo "pear" >> file2.txt # 对文件进行排序 (这是使用 comm 的前提!) sort file1.txt -o file1.txt sort file2.txt -o file2.txt # 查看文件内容 echo "--- file1.txt ---" cat file1.txt echo "--- file2.txt ---" cat file2.txt
如下:
--- file1.txt ---
apple
banana
grape
orange
--- file2.txt ---
banana
kiwi
orange
pear
现在我们来使用 comm 命令。
示例 1:默认输出(显示所有三列)
comm file1.txt file2.txt
输出:

apple banana grape
kiwi orange
pear
解读:
apple和grape只在file1.txt中,所以出现在第一列。kiwi和pear只在file2.txt中,所以出现在第二列。banana和orange在两个文件中都有,所以出现在第三列。
示例 2:只显示交集(两个文件共有的行)
使用 -12 选项来隐藏第一列和第二列。
comm -12 file1.txt file2.txt
输出:
banana
orange
这是 comm 命令一个非常常见的用法,用来查找两个文件的共同内容。
示例 3:只显示在 file1 中但不在 file2 中的行
使用 -23 选项来隐藏第二列和第三列。
comm -23 file1.txt file2.txt
输出:
apple
grape
示例 4:只显示在 file2 中但不在 file1 中的行
使用 -13 选项来隐藏第一列和第三列。
comm -13 file1.txt file2.txt
输出:
kiwi
pear
comm 与 diff、grep 的比较
comm、diff 和 grep 都可以用来比较文件,但它们的目的和输出方式不同。
| 命令 | 主要用途 | 输出特点 |
|---|---|---|
comm |
比较两个已排序文件,找出独有和共有的行。 | 输出三列,结构化,易于脚本处理。 |
diff |
比较两个文件的差异(添加、删除、修改)。 | 输出详细的补丁格式(a for add, c for change, d for delete),适合人类阅读和 patch 命令。 |
grep |
使用模式匹配来查找行。 | 通常通过管道组合使用,grep -f file1.txt file2.txt 来查找 file2 中包含 file1 内容的行。 |
常见用法与脚本技巧
comm 的真正威力在于它在 shell 脚本中的组合使用。
用法1:查找两个文件的交集(并排序)
comm -12 <(sort file1.txt) <(sort file2.txt)
<(...)是进程替换(Process Substitution),它允许将命令的输出像文件一样传递给另一个命令,这样你就不需要手动创建临时排序文件了。
用法2:查找在 file1 中但不在 file2 中的所有行
comm -23 <(sort file1.txt) <(sort file2.txt)
这在很多场景下非常有用,
- 找出系统中已安装但某个软件包列表中没有的软件包。
- 找出一份完整名单中缺失的条目。
用法3:查找两个文件的并集(去重后合并)
这个技巧稍微复杂一点,需要将 comm 的输出重新组合。
# 合并第一列和第二列,然后与第三列合并,最后再次排序去重 comm -12 file1.txt file2.txt | cat - <(comm -23 file1.txt file2.txt) <(comm -13 file1.txt file2.txt) | sort -u
或者更简洁地使用 sort 命令直接实现:
sort file1.txt file2.txt | uniq
可以看到,对于简单的并集和交集,sort + uniq 的组合通常更直接。
| 特性 | 描述 |
|---|---|
| 核心功能 | 比较两个已排序文件,输出独有和共有的行。 |
| 前提条件 | 输入文件必须已排序。 |
| 输出格式 | 三列,用 Tab 分隔。 |
| 主要优势 | 结构化输出,非常适合在 shell 脚本中进行后续处理,例如提取某一列。 |
| 常用场景 | 查找交集(comm -12)、查找差异(comm -23 / comm -13)。 |
| 替代方案 | 对于未排序的文件,可以使用 grep 或 diff,对于集合操作(并集、交集、差集),sort + uniq 的组合通常更通用和强大。 |
comm 的核心是“比较已排序文件”,它是一个小巧但功能强大的工具,掌握它能让你在处理文本文件时更加得心应手。
