适用场景
你有维护前后两份文件名清单、软件包名称清单,或者待处理项目清单,希望分别得到新增、移除和仍然存在的项目,可以使用 comm。本教程面向配备 GNU Coreutils 的 Linux,例如常见 Ubuntu、Debian 系统,资料核对日期为 2026 年 10 月 28 日。
本例比较的是“名称是否存在”。即使同名文件的内容已经改变,只要清单中的名称不变,也会被归入共有项。因此,结果适合用于清单核对,不能代替文件内容校验或备份完整性验证。
原理:先把清单变成有序集合
comm 接受两份按照相同规则排好序的文本,默认输出三列:第一列只在第一份文件中出现,第二列只在第二份文件中出现,第三列同时存在。数字选项表示隐藏对应列,例如隐藏第一、三列后,就只剩第二份独有的项目。
本教程约定第一份是旧清单,第二份是新清单,因此第二列代表新增,第一列代表移除。顺序一旦交换,解释也会交换。相关行为见 GNU comm 官方手册。
排序与比较还必须使用相同的地区规则。下面把这些操作放进同一个子 Shell,并设置 LC_ALL=C,避免中文环境和其他语言环境的排序结果混用。去重则让每个名称只代表一个集合成员。
准备工作
打开 Bash 终端,准备一个新的练习目录。示例使用临时目录存放自建清单,不会读取业务目录,也不需要管理员权限。命令中的 manual.pdf 等文字只是练习条目,并不要求磁盘上存在这些文件。
先检查工具能否正常调用:
comm --version
sort --version
如果系统提供的是其他实现,应先查看其本地帮助。后面的 --check-order 使用 GNU 选项,不应假定任何精简系统都支持。
分步骤操作
第一步:创建两份可解释的样本
整段复制下面的命令。外层圆括号创建子 Shell,工作目录和地区设置只影响这一段。
(
set -e
export LC_ALL=C
workdir=$(mktemp -d)
printf '练习目录:%s\n' "$workdir"
cd -- "$workdir"
printf '%s\n' 'manual.pdf' 'notes.txt' 'photo.jpg' 'notes.txt' > before.txt
printf '%s\n' 'report.csv' 'photo.jpg' 'manual.pdf' > after.txt
sort -u before.txt > before.sorted
sort -u after.txt > after.sorted
comm --check-order -13 before.sorted after.sorted > added.txt
comm --check-order -23 before.sorted after.sorted > removed.txt
comm --check-order -12 before.sorted after.sorted > common.txt
printf '新增项目:\n'
cat added.txt
printf '移除项目:\n'
cat removed.txt
printf '共有项目:\n'
cat common.txt
wc -l before.sorted after.sorted added.txt removed.txt common.txt
)
workdir 保存系统生成的真实练习目录路径。请记录第一行输出,后续可用文件管理器打开该目录。before.txt 和 after.txt 分别是旧、新清单,三个结果文件分别保存新增、移除和共有项目。
第二步:读懂排序与去重
旧清单故意把一个名称写了两次,也没有按字符顺序排列。sort -u 将相同文本合并并排序,输出到新的文件。这样后面的比较只回答“有没有这个名称”,不会把重复次数当成资产数量。
排序输出必须写入另一个文件,不能把输入文件直接作为普通重定向的输出目标,否则 Shell 可能先清空它。排序规则与去重细节可参考 GNU sort 官方手册。
第三步:理解三种筛选
-13 隐藏第一、三列,留下新清单独有项目;-23 留下旧清单独有项目;-12 留下共有项目。结果文件中不再需要用制表符区分三列,方便继续人工查看或提交审核。
--check-order 要求工具检查输入顺序。如果出现未排序错误,应重新确认排序步骤和地区设置,不要关闭检查后继续使用结果。
验证方法
本例新增结果应只有 report.csv,移除结果应只有 notes.txt,共有结果应有 manual.pdf 与 photo.jpg。去重后的旧、新清单各有三项。
再核对两个数量关系:旧清单项数等于移除项数加共有项数;新清单项数等于新增项数加共有项数。本例两边都应成立。这个检查能帮助发现看错文件或漏看结果,但不能证明源清单本身完整。
另外,comm 正常完成时,即使存在差异也会返回零。不能像使用某些差异工具那样,仅凭成功退出就断定两份清单相同。要检查新增、移除结果是否为空,并同时确认命令没有报错。
常见错误
第一种是旧、新顺序放反,导致把移除理解为新增。第二种是拿数字排序结果交给默认文本比较;本例应统一使用普通文本排序。
第三种是输入格式不一致,例如一份带 Windows 行尾、另一份带尾部空格,或者名称大小写不同。这些都会被视为不同文本。是否清理空格、是否忽略大小写,应由清单规则决定,不能为了让差异减少而盲目修改名称。
普通逐行清单也不能可靠表达包含换行符的文件名。若要处理任意文件名,应另行设计零字节分隔的采集和处理流程,不要直接扩展本例假定。
安全与回退
练习只生成报告,没有根据结果删除或移动任何真实文件。接入业务清单时,先复制输入到独立目录,保留原始版本,再执行同样的排序与比较。
尤其不要直接把“移除清单”交给删除命令,因为它表示旧清单独有名称,不代表这些名称对应的对象应该被删除。练习结束后,确认临时目录只含本次生成文件,再通过文件管理器清理;需要留档时,可以把输入、排序结果和三份差异报告一起保存。
参考资料与转载说明
本文依据上述公开资料进行中文原创整理,不是逐句翻译,也不替代厂商手册。操作前请核对自己的版本、型号和备份。
评论一下?