unix数字排序也会产生奇怪的结果。
$ cat example.csv # here's a small example
58,1.49270399401
59,0.000192136419373
59,0.00182092924724
59,1.49270399401
60,0.00182092924724
60,1.49270399401
12,13.080339685
12,14.1531049905
12,26.7613447051
12,50.4592437035
$ cat example.csv | sort -n --field-separator=,
58,1.49270399401
59,0.000192136419373
59,0.00182092924724
59,1.49270399401
60,0.00182092924724
60,1.49270399401
12,13.080339685
12,14.1531049905
12,26.7613447051
12,50.4592437035
对于此示例,无论是否指定分隔符,sort都会给出相同的结果。我知道如果我设置LC_ALL=C
然后排序开始再次给出预期的行为。但我不明白为什么默认环境设置(如下所示)会使这种情况发生。
$ 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=
我从许多其他问题中读过(例如here,here和here)如何避免排序中的这种行为,但是,这种行为仍然令人难以置信的奇怪和不可预测并且让我心痛了一周。有人可以解释为什么Mac OS X(10.8.5)上的默认环境设置排序会这样吗?换句话说:什么是排序(将局部变量设置为en_US.UTF-8)以获得该结果?
我正在使用
sort 5.93 November 2005
$ type sort
sort is /usr/bin/sort
我已经在gnu-coreutils列表上讨论了这个问题,现在明白为什么使用英语unicode默认语言环境设置进行排序可以得到输出。因为在英文unicode中,逗号字符“,”被认为是数字(以便允许逗号为千位(或例如数百)分隔符),并且在解释一行时将默认值排序为“贪婪”,它会读取示例数字约为
581.491...
590.000...
590.001...
591.492...
600.001...
601.492...
1213.08...
1214.15...
1226.76...
1250.45...
虽然这不是我想要的,而且chepner是正确的,以获得我想要的实际结果,我需要指定我想要排序只键入第一个字段。 sort默认将更多的行解释为键而不仅仅是第一个字段作为键。
这种排序行为已在gnu-coreutil的FAQ中讨论过,并在the POSIX description of sort中进一步说明。
所以,正如gnu-coreutil's list put it上的Eric Blake,如果字段分隔符也是数字(逗号是),那么“没有-k来阻止事物,[字段分隔符]就像两个一样分隔符和数字字符 - 您正在对跨越多个字段的数字进行排序。“
答案 0 :(得分:7)
我不确定这是完全正确的,但它很接近。
sort -n -t,
将尝试按给定的键进行数字排序。在这种情况下,键是一个由整数和浮点组成的元组。这样的元组不能用数字排序。
如果您明确指定要使用
排序的单个键sort -k1,1n -k2,2n -t,
它应该有用。现在,您明确告诉sort
首先对第一个字段(数字)进行排序,然后在第二个字段(也是数字上)进行排序。
我怀疑只有当输入的每一行都包含一个数值时,-n
才有用作全局选项。否则,您需要将-n
选项与-k
选项结合使用,以准确指定哪些字段是数字。
答案 1 :(得分:1)
使用sort --debug查找正在发生的事情。 我用它来详细解释你的问题: http://lists.gnu.org/archive/html/coreutils/2013-10/msg00004.html
答案 2 :(得分:0)
如果您使用
cat example.csv | sort
而不是
cat example.csv | sort -n --field-separator=,
然后它会给出正确的输出。使用此命令,希望这对您有所帮助。
注意:我测试了" sort(GNU coreutils)7.4"