免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7790 | 回复: 18
打印 上一主题 下一主题

sort的排序流程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-26 05:24 |只看该作者 |倒序浏览
本帖最后由 ywlscpl 于 2010-08-26 09:34 编辑

一家之言,欢迎探讨。

关于sort的使用,最常用的-k参数的使用,指定几个-k参数,就是指定几个排序关键域,且按顺序依次为第1、第2...关键域。
man sort对-k是这么解释的:
       -k, --key=POS1[,POS2]
              start a key at POS1, end it at POS2 (origin 1)

如果不是很明白,可以这样理解:
1、-k2,3,表示关键域是从第2列到第3列
2、总列数为m列时,sort -k2 等价于 sort -k2,m
关键对-k2,m的理解,应该是“从第2列起到第m列止的字符串”,对于-k2,3来说,关键域就是第2列到第3列止的字符串。

明确概念后,下面讲讲sort的排序流程。
PS:翻到很久以前的一个帖子
http://bbs.chinaunix.net/viewthr ... &ordertype=0&page=1该贴所问的“为什么已经用-k3n,3指定只用第三个域进行排序,sort仍然对第四个域进行了排序?”让我有了弄清sort排序机制的念头。

sort -k参数的排序流程,个人理解,欢迎讨论:
1、针对每个-k参数指定的排序关键域,依次作为第1、第2、第n关键域进行排序
2、针对这n个关键域的排序后的结果中,对于这n个关键域都相同的行,sort再对这些行进行一次默认resort(未resort前是以原始顺序排序的)。
若指定了-s参数(GNU sort),resort不会进行。
       -s, --stable
              stabilize sort by disabling last-resort comparison


依次解析各个例子:
例子1、可以看到针对关键域3进行排序后,不会按原始顺序输出,因为sort又再次进行了resort
[root@Mylinux tmp]# cat file3
uucp:5:5:UUCP administrator:/usr/lib/uucp:
uucp:6:2:UUCP administrator:/usr/lib/uucp:
uucp:5:3:UUCP administrator:/usr/lib/uucp:
uucp:6:1:UUCP administrator:/usr/lib/uucp:
[root@Mylinux tmp]# sort -t: -k3,3n file3
uucp:5:3:UUCP administrator:/usr/lib/uucp:
uucp:5:5:UUCP administrator:/usr/lib/uucp:
uucp:6:1:UUCP administrator:/usr/lib/uucp:
uucp:6:2:UUCP administrator:/usr/lib/uucp:

等价的awk模拟sort排序流程(-k2,2作用就是模拟sort的resort)
[root@Mylinux tmp]# awk -F: -v OFS=# '{print $3,$0}' file3
5#uucp:5:5:UUCP administrator:/usr/lib/uucp:
6#uucp:6:2:UUCP administrator:/usr/lib/uucp:
5#uucp:x:5:3:UUCP administrator:/usr/lib/uucp:
6#uucp:x:6:1:UUCP administrator:/usr/lib/uucp:
[root@Mylinux tmp]# awk -F: -v OFS=# '{print $3,$0}' file3 |sort -t# -k1,1n -k2,2
5#uucp:x:5:3:UUCP administrator:/usr/lib/uucp:
5#uucp:x:5:5:UUCP administrator:/usr/lib/uucp:
6#uucp:x:6:1:UUCP administrator:/usr/lib/uucp:
6#uucp:x:6:2:UUCP administrator:/usr/lib/uucp:
[root@Mylinux tmp]# awk -v OFS=# '{print $2" "$3" "$4,$0}' file3 | sort -t# -k1,1 -k2,2 | awk -F# '{print $2}'
uucp:x:5:3:UUCP administrator:/usr/lib/uucp:
uucp:x:5:5:UUCP administrator:/usr/lib/uucp:
uucp:x:6:1:UUCP administrator:/usr/lib/uucp:
uucp:x:6:2:UUCP administrator:/usr/lib/uucp:


例子2、
sort -k2等价于sort -k2,4,排序关键域为第2至第4域为止的字符串
[root@Mylinux tmp]# cat file
a 2 7 1
b 2 4 5
c 9 1 6
d 6 9 7
e 1 8 5
f 8 1 3
g 4 4 3
h 6 3 4
[root@Mylinux tmp]# sort -k2 file
e 1 8 5
b 2 4 5
a 2 7 1
g 4 4 3
h 6 3 4
d 6 9 7
f 8 1 3
c 9 1 6

等价awk模拟过程
[root@Mylinux tmp]# awk -v OFS=# '{print $2" "$3" "$4,$0}' file
2 7 1#a 2 7 1
2 4 5#b 2 4 5
9 1 6#c 9 1 6
6 9 7#d 6 9 7
1 8 5#e 1 8 5
8 1 3#f 8 1 3
4 4 3#g 4 4 3
6 3 4#h 6 3 4
[root@Mylinux tmp]# awk -v OFS=# '{print $2" "$3" "$4,$0}' file | sort -t# -k1,1 -k2,2
1 8 5#e 1 8 5
2 4 5#b 2 4 5
2 7 1#a 2 7 1
4 4 3#g 4 4 3
6 3 4#h 6 3 4
6 9 7#d 6 9 7
8 1 3#f 8 1 3
9 1 6#c 9 1 6
[root@Mylinux tmp]# awk -v OFS=# '{print $2" "$3" "$4,$0}' file | sort -t# -k1,1 -k2,2 | awk -F# '{print $2}'
e 1 8 5
b 2 4 5
a 2 7 1
g 4 4 3
h 6 3 4
d 6 9 7
f 8 1 3
c 9 1 6


例子3、
sort -k2n 等价于sort -k2,4n,可以看到排序结果跟sort -k2不一样了,关键在于前面所说的:
对-k2,m的理解,应该是“从第2列起到第m列止的字符串”,而加了n参数后,导致对这一关键域的排序结果变了
[root@Mylinux tmp]# cat file
a 2 7 1
b 2 4 5
c 9 1 6
d 6 9 7
e 1 8 5
f 8 1 3
g 4 4 3
h 6 3 4
[root@Mylinux tmp]# sort -k2n file
e 1 8 5
a 2 7 1
b 2 4 5
g 4 4 3
d 6 9 7
h 6 3 4
f 8 1 3
c 9 1 6

awk模拟sort流程
[root@Mylinux tmp]# awk -v OFS=# '{print $2" "$3" "$4,$0}' file
2 7 1#a 2 7 1
2 4 5#b 2 4 5
9 1 6#c 9 1 6
6 9 7#d 6 9 7
1 8 5#e 1 8 5
8 1 3#f 8 1 3
4 4 3#g 4 4 3
6 3 4#h 6 3 4
[root@Mylinux tmp]# awk -v OFS=# '{print $2" "$3" "$4,$0}' file | sort -t# -k1,1n -k2,2
1 8 5#e 1 8 5
2 7 1#a 2 7 1
2 4 5#b 2 4 5
4 4 3#g 4 4 3
6 9 7#d 6 9 7
6 3 4#h 6 3 4
8 1 3#f 8 1 3
9 1 6#c 9 1 6
[root@Mylinux tmp]# awk -v OFS=# '{print $2" "$3" "$4,$0}' file | sort -t# -k1,1n -k2,2 | awk -F# '{print $2}'
e 1 8 5
a 2 7 1
b 2 4 5
g 4 4 3
d 6 9 7
h 6 3 4
f 8 1 3
c 9 1 6


例4、
对此贴的例子进行验证http://bbs2.chinaunix.net/viewth ... 73591&extra=&page=1
>sort -t, -k2 -k4 file
c2,7,3,13
c1,7,6,24
b2,8,1,17
b1,8,7,15
a1,9,2,21
a2,9,4,11
>sort -t, -k2,2 -k4,4 file
c2,7,3,13
c1,7,6,24
b1,8,7,15
b2,8,1,17
a2,9,4,11
a1,9,2,21

sort -k2 -k4等价于sort -k2,4 -k4,4
[root@Mylinux tmp]# sort -t, -k2 -k4 file4
c2,7,3,13
c1,7,6,24
b2,8,1,17
b1,8,7,15
a1,9,2,21
a2,9,4,11
[root@Mylinux tmp]# awk -F, -v OFS=# '{print $2","$3","$4,$4,$0}' file4 | sort -t# -k1,1 -k2,2 -k3,3 | awk -F# '{print $NF}'                    
c2,7,3,13
c1,7,6,24
b2,8,1,17
b1,8,7,15
a1,9,2,21
a2,9,4,11
[root@Mylinux tmp]# sort -t, -k2,2 -k4,4 file4
c2,7,3,13
c1,7,6,24
b1,8,7,15
b2,8,1,17
a2,9,4,11
a1,9,2,21
[root@Mylinux tmp]# awk -F, -v OFS=# '{print $2,$4,$0}' file4 | sort -t# -k1,1 -k2,2 -k3,3 | awk -F# '{print $NF}'
c2,7,3,13
c1,7,6,24
b1,8,7,15
b2,8,1,17
a2,9,4,11
a1,9,2,21

论坛徽章:
0
2 [报告]
发表于 2010-08-26 09:04 |只看该作者
大家早,学习了

论坛徽章:
0
3 [报告]
发表于 2010-08-26 09:18 |只看该作者
回复 1# ywlscpl


    先顶下,再慢慢学习

论坛徽章:
0
4 [报告]
发表于 2010-08-26 09:19 |只看该作者
先收藏,以后再看!

论坛徽章:
0
5 [报告]
发表于 2010-08-26 09:25 |只看该作者
excellent

论坛徽章:
0
6 [报告]
发表于 2010-08-26 09:33 |只看该作者
例4貌似有点不太对?
  1. sort -k2 -k4等价于sort -k2,4 -k4,4
复制代码
这个不等价吧?

论坛徽章:
0
7 [报告]
发表于 2010-08-26 09:34 |只看该作者
沙发

论坛徽章:
0
8 [报告]
发表于 2010-08-26 09:42 |只看该作者
学习,LZ好早

论坛徽章:
0
9 [报告]
发表于 2010-08-26 09:45 |只看该作者

收下了。。

论坛徽章:
0
10 [报告]
发表于 2010-08-26 09:46 |只看该作者
回复 6# bbgg1983

sort -k2 -k4等价于sort -k2,4 -k4,4

第1排序关键域:第2至4列的字符串
第2关键域:第4列

其实第2关键域是多余的,因为第2关键域-k2,4相同的行,第2关键域肯定相同-k4,4

我只所以验证这个例子,是为了说明-k参数的使用,都可以套用这个流程。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP