comm:文件未排序


9

我曾经comm比较两个排序的文件。这些文件中的每一行都是正整数。但是结果显示

comm: file 1 is not in sorted order
comm: file 2 is not in sorted order

即使对这两个文件进行了排序,也会出现错误?


就我而言,我已经使用notepad ++对文件进行了排序(字典升序),该文件考虑了小写字母,而大写字母则分开。a将以升序出现在“ Z”之后。这与排序实用程序(bash)的排序方式不同。为了验证这一点,我将所有行都转换为大写,然后以np ++进行排序,不再抱怨comm。
萨希尔·辛格

Answers:


10

comm需要按字典顺序排序(plain sort),而不是数字排序(sort -n)。例如,它需要以下顺序:

1
2000
300

不是以下命令:

1
300
2000

更正此问题,该问题将消失。对于更深奥的情况下comm的语言环境可能会比不同sort的语言环境,你可能需要运行sort,并commLC_COLLATE=C他们的环境中使用本地字节顺序。


如何使它进行数字排序?
wenzi 2012年


在“ Lexographic Ordering ”中,一系列数字在有序的Seeries中增加-您在答案中已经倒数了:mathworld.wolfram.com/LexicographicOrder.html。请参考我的回答以下的测试结果比较其使用的sort ,并没有-n开关和仅演示-n开关就可以实现正确的增加你承认为了在你自己的答案是必需的。
F1Linux

@ F1Linux什么?comm字面上需要LC_COLLATEd排序。只需说出答案中的错误就并非纯粹出于测试集之外的示例而已...没人问过正数排序。
克里斯·

@ChrisDown您回答的我的答案-不是我看到的您刚刚编辑过的答案,只有现在提到“ LC_COLLATE ”是:“ comm需要字面文字排序,而不是数字排序。更正此问题应解决。 ”现在关于“ LC_COLLATE”的东西与“ _Lexographic”排序的兽完全不同。确实,您的最初答案非常稀疏,仅一行,没有任何示例,这促使我用自己的答案重新审视该问题。我赞成您更新的答案,因为正如您指出的,“ LC_COLLATE”在此绝对有效。
F1Linux

0

更新的答案:

问题:

当用于比较文件中的正整数而不是文本时,OP收到有关“ 文件未排序顺序 ” 的错误。因此,我们正在处理非十进制数字。comm

简短答案:

根据将-nswitch与sort提供给的结果进行排序的命令配合使用的情况comm,所返回的结果的顺序comm可能会非常不同:

Lexographic:将-n开关与sort一起使用将导致“正整数”以一系列递增的顺序排序。可以使用`s开关抑制“ 错误comm--nocheck-order

字节顺序:有使用的-n switchsortLC_COLLATE确定顺序,该顺序甚至可能因locale在执行命令的主机上设置的方式而异。这是comm默认情况下的预期输入。LC_COLLATE可以在这里找到更多有关信息:Reference1Reference2

错误是问题吗? 这取决于您要实现的目标。如您在以下示例中看到的,comm在比较带有 带有sort s-n开关的文件之后,返回相同的结果,尽管它们的顺序将根据是否-n switchsort命令一起使用以上述方式变化。我本人则更喜欢按“字典顺序”排序的结果数,其数量会逐级增加。

但是,如果您希望结果按“ 字典顺序”排序,则在对提供给比较的数据进行排序时,请勿使用该-n开关comm

测试:

我们将比较comm带有和不带有-n开关的命令的结果。根据Kusalananda的要求,我增加了样本测试数据集的复杂性:

测试数据

file1.txt

40
110000
2200
6
33000

file2.txt

2200
40
33000
6
440000

交叉点

仅列出两个文件共有的数字

不带-n开关:

comm -12 <(sort file1.txt) <(sort file2.txt)

2200
33000
40
6

结果:正确,但按未排序顺序返回

-n开关:

comm -12 <(sort -n file1.txt) <(sort -n file2.txt)

6
40
2200
33000
comm: file 1 is not in sorted order

结果:正确,但以LEXOGRAPHIC排序顺序返回。该操作成功完成,并且返回与使用comm不带-n开关的结果相同的结果,但排序列表中。

区别

仅列出每个文件唯一的数字:

不带-n开关:

comm -3 <(sort file1.txt) <(sort file2.txt)

110000
         440000

结果:正确-这些数字确实是每个文件专有的。

-n开关:

comm -3 <(sort -n file1.txt) <(sort -n file2.txt)

110000
comm: file 1 is not in sorted order
         440000

结果:正确,结果与comm不使用-n开关时相同,但是返回有关文件中未对正整数排序的错误。

印刷结果的解决方案:

使用comm`s --nocheck-order开关禁止显示错误消息。由于我们知道数字未在每个文件中排序,但是返回的结果comm -n是正确的,因此可以通过抑制它来安全地忽略该错误:

交叉点

comm -12 --nocheck-order <(sort -n file1.txt) <(sort -n file2.txt)

6
40
2200
33000

区别

comm -3 --nocheck-order <(sort -n file1.txt) <(sort -n file2.txt)

110000
         440000

结论:

返回给定的正整数返回排序时,错误“ 文件未排序comm并不意味着使用-n开关返回的结果comm是错误的。确实,使用会comm -n按排序顺序返回整洁的正确!

感谢@ dhag,@ kusalananda @ChrisDown提出了需要进一步扩展的问题。总是很高兴能对我的工作进行审查:唯一能够使自己变得更好的方法就是,如果我们不断受到同行的挑战和挑战。


投票最多的答案提到“通讯要按字典顺序排序”,但您似乎按数字排序。在某些情况下,它看起来会掉下来。
dhag

测试再次用数字那种不同的数字和字典顺序,如1000,200,30,4
Kusalananda

@Kusalananda刚刚在我更新的答案中加入了您非常有益的反馈。最有义务为您提供反馈!
F1Linux

@dhag刚刚更新了我的答案,以纳入您和Kusalanada的反馈。你们最愿意花时间和精力回顾我的
答案

1
@JeffSchaller我最初回答的答案提到的是“ Lexographic”排序,而不是像Chris新修订的答案中的“ LC_COLLATE”。我对克里斯的回答是正确的,并支持他的最新答案。“ Lexographic”和“ LC_COLLATE”是不同的野兽。感谢Jeff-
F1Linux
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.