gab*_*abe 5 unix csv sorting locale
即使我指定了分隔符,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
Run Code Online (Sandbox Code Playgroud)
对于此示例,无论是否指定分隔符,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=
Run Code Online (Sandbox Code Playgroud)
我从许多其他问题(例如这里,这里和这里)中读到了如何避免这种行为,但是,这种行为令人难以置信的奇怪和不可预测,并引起了我一周的心痛.有人可以解释为什么Mac OS X(10.8.5)上的默认环境设置排序会这样吗?换句话说:什么是排序(使用局部变量设置为en_US.UTF-8)来获得该结果?
我正在使用
sort 5.93 November 2005
$ type sort
sort is /usr/bin/sort
Run Code Online (Sandbox Code Playgroud)
我已经在gnu-coreutils列表上讨论了这个问题,现在明白为什么使用英语unicode默认语言环境设置进行排序可以得到输出.因为在英文unicode中,逗号字符","被认为是数字(以便允许逗号为千位(或例如数百)分隔符),并且在解释一行时将默认值排序为"贪婪",它会读取示例数字约为
581.491...
590.000...
590.001...
591.492...
600.001...
601.492...
1213.08...
1214.15...
1226.76...
1250.45...
Run Code Online (Sandbox Code Playgroud)
虽然这不是我想要的,而且chepner是正确的,为了获得我想要的实际结果,我需要指定我想要排序只键入第一个字段.sort默认将更多的行解释为键而不仅仅是第一个字段作为键.
sort的这种行为已在gnu-coreutil的FAQ中讨论过,并在POSIX的sort描述中进一步说明.
因此,正如gnu-coreutil列表中的 Eric Blake 所说,如果字段分隔符也是数字(逗号是),那么"没有-k来阻止事物,[字段分隔符]就像分隔符一样和一个数字字符 - 你正在排序跨越多个字段的数字."
我不确定这是完全正确的,但它很接近.
sort -n -t,将尝试按给定的键进行数字排序.在这种情况下,键是一个由整数和浮点组成的元组.这样的元组不能用数字排序.
如果您明确指定要排序的单个键
sort -k1,1n -k2,2n -t,
Run Code Online (Sandbox Code Playgroud)
它应该工作.现在你明确告诉了sort首先对第一个字段(数字)进行排序,然后在第二个字段(也是数字上)进行排序.
我怀疑-n只有当输入的每一行都包含一个数值时,它才有用作全局选项.否则,您需要将该-n选项与-k选项结合使用,以准确指定哪些字段是数字.
| 归档时间: |
|
| 查看次数: |
1585 次 |
| 最近记录: |