我有两个文件,每行只列出一堆不同的文件名。我合并了它们,对它们进行了排序,然后检查了comm
输出并发现了一些非常有趣的东西。
$ sort -u -o list1 list1
$ sort -u -o list2 list2
$ cat list1 list2 > combined
$ wc -l list1
18141 list1
$ wc -l list2
21755 list2
$ wc -l combined
39896 combined
$ sort -u -o combined combined
$ wc -l combined
24400 combined
$ comm -23 list1 combined | wc -l
12889
$ comm -13 list1 combined | wc -l
19148
$ comm -12 list1 combined | wc -l
5252
$ comm -23 list2 combined | wc -l
0
$ comm -13 list2 combined | wc -l
2645
$ comm -12 list2 combined | wc -l
21755
(为了清晰起见,在上面划线)
最后几次拨打comm
的电话是怎么回事?当我将list1
与combined
进行比较时,输出很古怪,但当我将list2
与combined
进行比较时,输出似乎没问题。
我甚至试图再次组合所有三个列表并测试:
$ cat list1 list2 combined > combined-again
$ wc -l combined-again
64296 combined-again
$ sort -u -o combined-again combined-again
$ wc -l combined-again
24400 combined-again
$ diff combined combined-again
combined
和combined-again
的排序唯一行数匹配,diff
没有输出!
$ comm combined combined-again | wc -l
24400
$ comm -12 combined combined-again | wc -l
24400
$ comm -3 combined combined-again | wc -l
0
这些comm
输出有意义,两个文件之间不应有任何区别。
$ comm -23 list1 combined-again | wc -l
12889
$ comm -13 list1 combined-again | wc -l
19148
$ comm -12 list1 combined-again | wc -l
5252
与list1
进行比较时,我们再次看到相同的数字。
$ comm -23 list2 combined-again | wc -l
0
$ comm -13 list2 combined-again | wc -l
2645
$ comm -12 list2 combined-again | wc -l
21755
与list2
进行比较时,数字是正确的。
我甚至使用comm -23 list1 combined-again
到grep
的某些输出行来表示combined-again
中的那些行,这些行确实存在。我完全不知道为什么在这种情况下comm
输出有问题...
$ locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=
每个文件都不包含奇怪的符号或字符,只包含使用驼峰的包名称。例如:
$ head list1
AAAAuthentication
AAACorrelationAPI
AAACorrespondence
AAATestSuite
AESDescription
AESImplementation
AESLogging
AESMaster
AESProofSystem
AESTestSuite
由于评论中的一些建议,经过一些更多的调查后,似乎问题可能是由于comm
和sort
工具的版本控制。
我在mac上运行了上述所有命令,其中comm
来自BSD 2005年1月26日,sort
来自GNU coreutils,2005年11月排序5.93。
在Linux框中,comm
和sort
都来自2012年1月的GNU coreutils 8.4,并且调用工作正常。
我想现在的问题是:版本控制之间存在差异,为什么它会影响comm
输出,如上所示?
答案 0 :(得分:1)
要使comm
起作用,需要对其输入进行排序。它需要与您的sort
一致,了解要使用的排序方法。在C语言环境(LC_ALL=C
)中,这很容易。字符串一次比较一个字节,并且不同的第一个字节决定顺序。
在en_US.UTF-8
语言环境中,它更难。首先,没有单一的权威机构描述预期的行为到底是什么。每个供应商都可以自由地想象"英语排序顺序,美国变体"手段。然后记录该决定与否(通常他们选择"不是")。当你的工具是BSD的一半,一半来自GNU时,分歧的机会增加了(虽然从理论上讲,我认为它们都应该遵循本地C库...)
使用LC_ALL=C
运行所有命令会使他们更有可能彼此达成一致。