按数字排序

按数字排序

我有一个名为的文件,data其内容是

id,col1,col2
0,-0.3479417882673812,0.5664382596767175
1,-0.26800930980980764,0.2952025161991604
2,-0.4159790791116641,-1.3375045524610152
3,-0.7859665489205871,-0.6428101880909471
4,-1.3922759043388822,-1.676262144826317
5,-1.2471867496427498,-0.4912119581361516
6,1.443385383041667,1.6974039491263593
7,-2.058899802821969,2.0607628464079917
8,-0.10641338441541626,0.035929568275064216
9,-0.517273684861199,-0.6184800988804992
10,-0.9934859021679552,1.0577312348984502
11,0.5923834706792905,-0.6693757541250825
12,0.8657741917554445,-0.6876271057571398
13,-1.2061097548360489,-0.7402582563022937
14,0.78768021182158,-0.38607117005262315

-n对第一列进行数字排序 ( ) 给出

$ sort -nk1 -t"," data
0,-0.3479417882673812,0.5664382596767175
id,col1,col2
1,-0.26800930980980764,0.2952025161991604
2,-0.4159790791116641,-1.3375045524610152
3,-0.7859665489205871,-0.6428101880909471
4,-1.3922759043388822,-1.676262144826317
5,-1.2471867496427498,-0.4912119581361516
7,-2.058899802821969,2.0607628464079917
8,-0.10641338441541626,0.035929568275064216
9,-0.517273684861199,-0.6184800988804992
10,-0.9934859021679552,1.0577312348984502
13,-1.2061097548360489,-0.7402582563022937
6,1.443385383041667,1.6974039491263593
11,0.5923834706792905,-0.6693757541250825
12,0.8657741917554445,-0.6876271057571398
14,0.78768021182158,-0.38607117005262315

这对我来说绝对是奇怪的。我在手册页中读到-n应该是数字排序。为什么要id放在数字之间?它是如何既10大于9又小于6,同时又11大于它们的呢?

似乎-g按照我想要的方式工作(而且我认为这是自然的),但这个-n选项完全让我无法理解。这是关于什么的?我认为它可能与区域设置有关,但是一旦我将分隔符指定为 being ,,我认为这无法解释它。

答案1

长话短说

使用sort -nk1,1 -t,或以其他方式-k1对整行进行排序,其中,数字被丢弃,因为它被解释为千位分隔符。

细节

在英语语言环境中,,是千位分隔符,它sort忽略数字的整数部分。

换句话说,在英语语言环境中,或任何,有千位分隔符的语言环境中(请参阅 的输出locale thousands_sep),当sort -nsees时11,000,000,它不会看到后面11跟着一些被忽略的垃圾的数字,而是看到11000000数字。同样11,0不是11但是110

现在(这是很多人都会遇到的问题),-k1定义一个从第一个字段开始的键,但由于您没有指定它停止的位置,因此在行尾结束,因此排序键是整行,是默认值。

所以sort -nk1 -t,与 完全相同sort -n

忽略,千位分隔符,您的输入sort实际上是对这些数字进行排序:

0
1
2
3
4
5
61.4433853830416671
7
8
9
10
110.5923834706792905
120.8657741917554445
13
140.78768021182158

所以这不是6vs 10vs 11,而是61.4433853830416671vs 10vs 110.5923834706792905

在这里,您想要:

sort -nk1,1 -t,

仅对第一个分隔字段进行排序,-k1,1定义一个排序键,该排序键从第一个字段的开头开始,到第一个字段的结尾结束。

您还可以sort -n在 C 语言环境中使用,其中,既不是小数基数也不是千位分隔符(并且.是小数基数):

LC_ALL=C sort -n

sort -g工作方式不同,因为sortthen 使用strtold()将键解释为数字并且strtold()不识别千位分隔符。

id标题行而言,在数字比较中,这id...被解释为0那里看不到数字。它在以 开头的行之后排序,0因为当两个记录排序相同时(此处为-n数字比较)sort会执行最后手段比较这是一个词汇的整行的比较(以及0之前的排序i)。

通过一些sort实现,最后手段比较可以通过 禁用-s。这里LC_ALL=C sort -sn会将id行放在前面,但这只是因为输入中没有负键(id(数字上又是 0)仍会排序在 后面-1)。如果你想从排序中排除第一行,你可以这样做:

(head -n1; LC_ALL=C sort -n) < file

相关内容