本帖最后由 ywlscpl 于 2010-08-26 09:34 编辑
一家之言,欢迎探讨。
关于sort的使用,最常用的-k参数的使用,指定几个-k参数,就是指定几个排序关键域,且按顺序依次为第1、第2...关键域。
man sort对-k是这么解释的:
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不会进行。
stabilize sort by disabling last-resort comparison
依次解析各个例子:
例子1、可以看到针对关键域3进行排序后,不会按原始顺序输出,因为sort又再次进行了resort
uucp:x:5:5:UUCP administrator:/usr/lib/uucp:
uucp:x:6:2:UUCP administrator:/usr/lib/uucp:
uucp:x:5:3:UUCP administrator:/usr/lib/uucp:
uucp:x:6:1:UUCP administrator:/usr/lib/uucp:
[root@Mylinux tmp]# sort -t: -k3,3n file3
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:
等价的awk模拟sort排序流程(-k2,2作用就是模拟sort的resort)
5#uucp:x:5:5:UUCP administrator:/usr/lib/uucp:
6#uucp:x: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域为止的字符串
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模拟过程
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参数后,导致对这一关键域的排序结果变了
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流程
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
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
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
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