comm
定义
comm在编程领域主要有两种含义。其一是Unix及类Unix系统中的标准命令行工具,用于逐行比较2个已排序的文本文件,并输出二者的差异与交集;该工具列入POSIX标准,GNU版本收录于coreutils软件包[1][2]。
其二是汇编器中的.comm伪指令(directive),用于声明一个名为指定名称的公共符号(common symbol),并把该符号占用的字节数一并交给链接器处理[3]。两者都属于底层工具链的一部分,前者面向文本数据比对,后者面向目标文件与链接过程。
以命令行工具为例,其调用形式为comm [选项]... 文件1 文件2,其中任一文件名为“-”时从标准输入读取,但两者同为“-”时POSIX未定义其行为[1]。
原理
comm的工作前提是两个输入文件已经按当地排序规则排好序。GNU手册指出,使用comm之前需用LC_COLLATE指定的collating顺序对文件排序,不带参数的sort命令输出的文件总是适合作为comm的输入[1]。有了有序输入,工具只需对两路序列做一次线性归并,即可判定每一行的归属,因此实现简单且执行效率高[1]。
无选项时comm输出3列:第1列仅出现在文件1中的行,第2列仅出现在文件2中的行,第3列为两文件共有的行;列与列之间以单个制表符分隔[1]。选项-1、-2、-3分别抑制对应列的打印,连同其分隔符一起省略[4]。
汇编侧的原理不同。.comm声明公共符号后,链接时某目标文件中的公共符号可以与另一目标文件中同名的已定义符号或公共符号合并;若链接器只见到公共符号而未见定义,则按声明的长度分配未初始化的内存[5]。出现多个同名公共符号且长度不一致时,链接器以最大的那个长度为准分配空间[5]。在ELF格式下还可给出第3个可选参数,用来指定符号的对齐方式,该值必须为2的幂[5]。
com
应用
命令行的典型用法是提取交集与差集。comm -12 文件1 文件2只打印同时存在于两个文件中的行,comm -3 文件1 文件2则打印只在其中一个文件里出现的行[4]。这类组合常出现在处理名单、词表、日志等场景的shell脚本中。
GNU扩展提供了若干便利选项:--output-delimiter=STR 可替换默认的制表符分隔符,--total 在末尾输出各列总行数的摘要,-z 改用NUL字符作为行尾分隔,便于与xargs -0等工具配合处理含空格的文件名[1]。较新的coreutils手册以9.1版本、2022年9月的页面形式发布这些说明[2]。
在编译与链接流程中,.comm主要作为编译器生成代码的中间形式出现。GNU工具链社区讨论提到,gcc会为未预先初始化且非静态的全局变量生成.comm声明,链接器随后把同名的这类变量归并并放置在.bss段中[6]。MASM中亦有同名的COMM伪指令,用于创建由链接器分配、不能初始化的公共变量[7]。
此外,在Java ME的通用连接框架中,comm:是一种打开逻辑串口的URI方案前缀,用以指定端口标识及波特率、校验位等参数[8]。
发展历程
comm命令行工具被纳入POSIX标准,并在20世纪80年代中后期于Unix系系统上被广泛使用[9]。GNU版本的实现由Richard M. Stallman与David MacKenzie编写,随coreutils一同分发[2]。2018年7月发布的GNU coreutils 8.30手册页与2022年9月的9.1手册页中,均列有该命令及--total等选项[10][2]。
.comm伪指令在GNU汇编器中长期存在,其ELF平台上的第3个对齐参数后来成为通用扩展;不同目标平台上的语法略有差异,例如HPPA平台的写法为symbol .comm, length[3]。围绕该指令也出现过工程讨论,有开发者指出同名公共变量的自动合并会妨碍--gc-sections等优化手段[6]。
局限
命令行comm要求输入有序,这一前提构成主要限制。若文件未按LC_COLLATE规则排序,结果没有保证;使用--check-order时未排序输入会直接报错退出,使用--nocheck-order则不做检查,但此时的输出不保证符合预期[1]。此外,若输入行本身以分隔字符开头,3列的划分在阅读时可能产生歧义[9]。
与diff相比,comm功能更简单,只适合脚本中的集合式比对;它不保留原始行序信息,排序前的顺序在输出中已不可恢复[9]。其退出状态也与比较结果无关,正常完成即返回0,不能靠返回值判断两文件是否相同[1]。
.comm侧的限制在于语义的宽松:公共符号会在链接期被合并,多个同名且大小不同的声明只取最大长度,多余的空间不会被报告[5]。公共变量不能给出初值,其位置与顺序也无法依赖[7]。ELF下对齐参数的解释依平台而定,误用可能触发链接错误[5]。
参见
参考资料
- comm-invocation [引用日期2026-10-29]
- comm(1) — manpages-zh — Debian trixie [引用日期2026-10-29]
- Comm [引用日期2026-10-29]
- Ubuntu Manpage: 名稱 [引用日期2026-10-29]
- comm [引用日期2026-10-29]
- Question about keywords and declarations in assembly code [引用日期2026-10-29]
- comm [引用日期2026-10-29]
- CommConnection [引用日期2026-10-29]
- Comm: 두 판 사이의 차이 - 위키백과, 우리 모두의 백과사전 [引用日期2026-10-29]
- マニュアルページ セクション 1: ユーザーコマンド [引用日期2026-10-29]