sort排序-k 感觉不按常规出牌

来源:互联网 发布:面试 职业规划 知乎 编辑:程序博客网 时间:2024/05/14 22:27

原始数据如下:
fdasfdas 40 0 30 0
dffdfdsf 30 0 50 0
efdasfdf 30 0 40 0
fdfjksdf 20 0 40 0

执行sort -nr -k2 a.txt 后,结果如下:
fdasfdas 40 0 30 0
efdasfdf 30 0 40 0  //感觉这一行应该和第三行互换,因为50大于40嘛,即sort -nr -k2 a.txt相当于sort -nr -k2,5 a.txt
dffdfdsf 30 0 50 0
fdfjksdf 20 0 40 0

执行sort -r -k2 a.txt 后,结果如下(正常的,即按照字符排序):
fdasfdas 40 0 30 0
dffdfdsf 30 0 50 0
efdasfdf 30 0 40 0
fdfjksdf 20 0 40 0

 

这是重排引起的。加 -s 就行了。

 

刚试了下,确实正常了,sort -k2(相当于sort -k2,5)是不是意思是?(哪种呢)
1.从第2列开始排序,先排列第2列,遇到相等的,就排列第三列,以此类推
2.把第2列到最后一列组成一列,然后排序

应该是按照第一种理解吧?

如果不加-s,那么排列完后,还得按照第1列再次排序?
但是2 3 4 5列排序完后,并没有相等的了啊,应该按照第一列排序无效啊,为何还会影响结果呢?
谢谢哈,不太理解

 

我又实验了下:
原始数据:
fdasfdas 30 0 30 0
dffdfdsf 30 0 50 0
efdasfdf 30 0 40 0
fdfjksdf 20 0 40 0
经过 sort -snr -k2 a.txt 后

fdasfdas 30 0 30 0  // 前3行没有按照第4列的降序进行排列啊
dffdfdsf 30 0 50 0
efdasfdf 30 0 40 0
fdfjksdf 20 0 40 0

 

对于你的数据,
sor -nr -k 2 相当于
先按 2字段进行数值逆序排序,再按 1,3,4,5进行字符串逆序排序(重排)

 

嗯,从结果上看,确实是这样的,但是:
你说:
   对于你的数据,
sor -nr -k 2 相当于
先按 2字段进行数值逆序排序,再按 1,3,4,5进行字符串逆序排序(重排)

但是我感觉sort -nr -k2,2才是先按照2字段进行逆序排列,再按照1 3 4 5重排。
而sort -nr -k2相当于sort -nr -k2,5,是先按照2,3,4,5排序,然后再按照1重排。

可能我理解的不对,您能说下
sor -nr -k 2
sort -nr -k2,2
的区别吗,谢谢了,我看了很多资料,感觉都是按我那个理解说的,比如:

////////////////////////////////////////////////////////////////////////////////////////
6 -k选项的具体语法格式
要继续往下深入的话,就不得不来点理论知识。你需要了解-k选项的语法格式,如下:

[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]

这个语法格式可以被其中的逗号(“,”)分为两大部分,Start部分和End部分。

先给你灌输一个思想,那就是“如果不设定End部分,那么就认为End被设定为行尾”。这个概念很重要的,但往往你不会重视它。

Start部分也由三部分组成,其中的Modifier部分就是我们之前说过的类似n和r的选项部分。我们重点说说Start部分的FStart和C.Start。

C.Start也是可以省略的,省略的话就表示从本域的开头部分开始。之前例子中的-k 2和-k 3就是省略了C.Start的例子喽。

FStart.CStart,其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。

同理,在End部分中,你可以设定FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将CEnd设定为0(零),也是表示结尾到“域尾”。

###也就是说,如果只写-k2,相当于-k2,m(m是总的列数)
////////////////////////////////////////////////////////////////////////////////////////

而:
////////////////////////////////////////////////////////////////////////////////////////
11 最诡异的排序:

$ sort -n -k 2.2,3.1 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

以第二个域的第二个字符开始到第三个域的第一个字符结束的部分进行排序。

第一行,会提取0 3,第二行提取00 5,第三行提取00 4,第四行提取10 5。

又因为sort认为0小于00小于000小于0000….

因此0 3肯定是在第一个。10 5肯定是在最后一个。但为什么00 5却在00 4前面呢?(你可以自己做实验思考一下。)

答案揭晓:原来“跨域的设定是个假象”,sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分,而不会把第三个域的开头字符纳入比较范围。当发现00和00相同时,sort就会自动比较第一个域去了。当然baidu在sohu前面了。用一个范例即可证实:

$ sort -n -k 2.2,3.1 -k 1,1r facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

###这个说法也确实让人摸不到头脑,明明说按照第2列的第二个字符到第三列第一个字符,结果确实没有使用第三列,不知道为啥还要搞个-kn,m干什么?
////////////////////////////////////////////////////////////////////////////////////////

 

我大概明白了,-k2,5是指 按照第二列排序,如果行的第二到第五个元素都相同,则进行重排,即再次从第1列排序

但是指定-n后,第一列四海字母,它是如何排序的啊

 

还有个问题哈

就是如何忽略第一列,即假设从第二列排序,有重复的,再次排序的序列为3 4 5,而不是 1 3 4 5

 

分别指定,如 sor -rn -k2,2 -k3,3 -k4,4

 

http://bbs.chinaunix.net/thread-3761228-1-1.html

0 0