comm 是什么
comm 是 coreutils 里的集合比较工具,逐行比较两个已排序文件并输出三列:只在文件一出现的行、只在文件二出现的行、两边都有的行。用 -1、-2、-3 抑制对应列,就能分别得到交集与两个方向的差集。它的杀手场景是清单比对:两台机器的软件包名、两个环境的配置项、迁移前后的文件列表、依赖白名单校验,都是一条命令出结果。前提是输入必须按相同排序规则排好序,否则输出没有意义。
基本信息
| 适用平台 | GNU/Linux、macOS(BSD 与 GNU 行为基本一致) |
|---|---|
| 语法 | comm [选项] 文件1 文件2 |
| 前置要求 | 两个文件都必须已按相同排序规则排序 |
| 列含义 | 第一列 仅文件1;第二列 仅文件2;第三列 两者共有 |
| 常用选项 | -1 -2 -3 抑制对应列,可任意组合 |
| 分隔符 | 列之间用制表符分隔 |
典型使用场景
- 比对两台服务器安装的软件包清单,找出只在一台存在的包。
- 核对两个环境的配置键是否一致,上线前发现遗漏项。
- 检查备份清单与源目录文件清单的差集,确认有没有漏备文件。
- 比对两个版本导出的域名或 IP 列表,做迁移前后的一致性核对。
- 在流水线里做白名单校验:把实际使用的依赖与允许列表求差集,非空即告警。
常用写法
常用写法
LC_ALL=C sort -u a.txt > a.sorted # 统一排序规则并去重
LC_ALL=C sort -u b.txt > b.sorted
comm a.sorted b.sorted # 三列全看:两边独有 + 共有
comm -12 a.sorted b.sorted # 只看共有(两文件的交集)
comm -23 a.sorted b.sorted # 只在 a 中(a 独有的差集)
comm -13 a.sorted b.sorted # 只在 b 中
comm -3 a.sorted b.sorted | sed 's/^[[:blank:]]*//' # 去掉列缩进后输出
comm -12 <(sort -u x.txt) <(sort -u y.txt) # 进程替换,免落盘抑制列组合读法
| 用法 | 含义 | 典型用途 |
|---|---|---|
| 默认不抑制 | 三列全输出 | 人工核对完整差异 |
| -12 | 隐藏前两列 | 只看交集 |
| -23 | 隐藏第二三列 | 只看文件1 独有的行 |
| -13 | 隐藏第一三列 | 只看文件2 独有的行 |
| -3 | 隐藏第三列 | 只看两边各自独有的差异 |
| -123 | 全部隐藏 | 无输出即两文件内容完全相同 |
排序规则必须完全一致:一边用 LC_ALL=C、另一边用中文 locale,或一边 sort -n 一边默认字典序,比较结果都会错。做集合比较时统一在两侧都加 LC_ALL=C,这是最省心的做法。
输入未排序时 GNU comm 只打印一行 not in sorted order 的提示然后照常输出,很容易被当成真实差异;稳妥流程是先各自 sort -u 落盘,再比对。
comm 的输出列用制表符分隔,想抑制列就用 -1/-2/-3,不要用 cut 硬切——切列会因制表符被替换成空格而错位。