sort命令使用说明

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

sort命令使⽤说明
1、命令概述
sort命令是在Linux⾥⾮常有⽤,它将⽂件进⾏排序,并将排序结果标准输出。

sort命令既可以从特定的⽂件,也可以从stdin中获取输⼊。

2、命令语法
sort 【选项】【⽂件】
3、命令选项
-b:忽略每⾏前⾯开始出的空格字符
-c:检查⽂件是否已经按照顺序排序
-d:排序时,处理英⽂字母、数字及空格字符外,忽略其他的字符
-f:排序时,将⼩写字母视为⼤写字母(忽略⼤⼩写)
-g:按通⽤数值排序,⽀持科学计数法
-i:排序时,除了040⾄176之间的ASCII字符外,忽略其他的字符
-m:将⼏个排序号的⽂件进⾏合并
-M:将前⾯3个字母依照⽉份的缩写进⾏排序
-n:依照数值的⼤⼩排序
-o <输出⽂件>:将排序后的结果存⼊原⽂件
-r:以相反的顺序来排序,
-k:指定需要排序的栏位
-t <分隔字符>:指定排序时所⽤的栏位分隔字符
-u:去除重复的⾏
4、命令⽰例
4.1 sort将⽂件/⽂本的每⼀⾏作为⼀个单位,相互⽐较,⽐较原则是从⾸字符向后,依次按ASCII码值进⾏⽐较,最后将他们按升序输出: 1 [root@lzg ~]# cat a.txt
25
311
41
5156
611
723
8156
9256
10 [root@lzg ~]# sort a.txt
111
1211
1311
14156
15156
1623
17256
185
19 [root@lzg ~]# cat b.txt
20 aaa:30:1.6
21 bbb:10:2.5
22 ccc:50:3.3
23 ddd:20:4.2
24 bbb:10:2.5
25 eee:80:5.4
26 eee:60:5.1
27 [root@lzg ~]# sort b.txt
28 aaa:30:1.6
29 bbb:10:2.5
30 bbb:10:2.5
31 ccc:50:3.3
32 ddd:20:4.2
33 eee:60:5.1
34 eee:80:5.4
35 [root@lzg ~]#
4.2 忽略相同⾏使⽤-u选项或者uniq:
1 [root@lzg ~]# sort a.txt
21
311
411
5156
6156
723
8256
95
10 [root@lzg ~]# sort -u a.txt
111
1211
13156
1423
15256
165
17 [root@lzg ~]# sort b.txt
18 aaa:30:1.6
19 bbb:10:2.5
20 bbb:10:2.5
21 ccc:50:3.3
22 ddd:20:4.2
23 eee:60:5.1
24 eee:80:5.4
25 [root@lzg ~]# sort -u b.txt
26 aaa:30:1.6
27 bbb:10:2.5
28 ccc:50:3.3
29 ddd:20:4.2
30 eee:60:5.1
31 eee:80:5.4
32 [root@lzg ~]#
或者使⽤uniq:
1 [root@lzg ~]# sort a.txt
21
311
411
5156
6156
723
8256
95
10 [root@lzg ~]# sort a.txt | uniq
111
1211
13156
1423
15256
165
17 [root@lzg ~]# sort b.txt
18 aaa:30:1.6
19 bbb:10:2.5
20 bbb:10:2.5
21 ccc:50:3.3
22 ddd:20:4.2
23 eee:60:5.1
24 eee:80:5.4
25 [root@lzg ~]# sort b.txt | uniq
26 aaa:30:1.6
27 bbb:10:2.5
28 ccc:50:3.3
29 ddd:20:4.2
30 eee:60:5.1
31 eee:80:5.4
32 [root@lzg ~]#
4.3 -n 依照数值的⼤⼩顺序排列:
1 [root@lzg ~]# cat a.txt
25
311
41
5156
611
723
8156
9256
10 [root@lzg ~]# sort -n a.txt
111
125
1311
1411
1523
16156
17156
18256
19 [root@lzg ~]# cat b.txt
20 aaa:30:1.6
21 bbb:10:2.5
22 ccc:50:3.3
23 ddd:20:4.2
24 bbb:10:2.5
25 eee:80:5.4
26 eee:60:5.1
27 [root@lzg ~]# sort -n b.txt
28 aaa:30:1.6
29 bbb:10:2.5
30 bbb:10:2.5
31 ccc:50:3.3
32 ddd:20:4.2
33 eee:60:5.1
34 eee:80:5.4
35 [root@lzg ~]#
4.4 -o <输出⽂件>:将排序后的结果存⼊原⽂件。

由于sort默认是把结果输出到标准输出,所以需要⽤重定向才能将结果写⼊⽂件,形如sort filename > newfile。

但是,如果你想把排序结果输出到原⽂件中,⽤重定向可就不⾏了。

1 [root@lzg ~]# ls
2 a.txt b.txt c.txt
3 [root@lzg ~]# cat c.txt
48
51
63
72
8 [root@lzg ~]# sort c.txt
91
102
113
128
13 [root@lzg ~]# sort c.txt > d.txt #输出结果重定向到d.txt
14 [root@lzg ~]# ls
15 a.txt b.txt c.txt d.txt
16 [root@lzg ~]# cat d.txt #查看内容,排序后的
171
182
193
208
21 [root@lzg ~]# sort c.txt > c.txt #类似⽅法重定向到原⽂件 c.txt
22 [root@lzg ~]# ls
23 a.txt b.txt c.txt d.txt
24 [root@lzg ~]# cat c.txt #查看内容,将原⽂件清空了
25 [root@lzg ~]#
这个时候可以使⽤ -o 选项,将结果写⼊原⽂件。

1 [root@lzg ~]# cat c.txt
28
31
43
52
6 [root@lzg ~]# sort c.txt -o c.txt
7 [root@lzg ~]# cat c.txt
81
92
103
118
12 [root@lzg ~]#
4.5 -c:检查⽂件是否已经按照顺序排序
1 [root@lzg ~]# cat a.txt
25 dsfsd 5000300
31 hyj 1000600
4156 efcv 4000700
511 ghjty 600566
623 rfdfg 7569500
7256 hjtf 6000230
8 [root@lzg ~]# sort -c a.txt
9 sort: a.txt:2: disorder: 1 hyj 1000600 #提⽰⽆序
10 [root@lzg ~]# cat c.txt
111
122
133
148
15 [root@lzg ~]# sort -c c.txt #已排序的,没有提⽰
4.6 sort的-n、-r、-k、-t选项的使⽤:
1 [root@lzg ~]# cat b.txt
2 aaa:30:1.6
3 bbb:10:2.5
4 ccc:50:3.3
5 ddd:20:4.2
6 bbb:10:2.5
7 eee:80:5.4
8 eee:60:5.1
9 [root@lzg ~]# sort -n -k2 -t: b.txt
10 bbb:10:2.5
11 bbb:10:2.5
12 ddd:20:4.2
13 aaa:30:1.6
14 ccc:50:3.3
15 eee:60:5.1
16 eee:80:5.4
17 [root@lzg ~]# sort -nr -k3 -t: b.txt
18 eee:80:5.4
19 eee:60:5.1
20 ddd:20:4.2
21 ccc:50:3.3
22 bbb:10:2.5
23 bbb:10:2.5
24 aaa:30:1.6
25 [root@lzg ~]#
#-n是按照数字⼤⼩排序,-r是以相反顺序,-k是指定需要排序的栏位、2是代表第⼆栏的,-t指定栏位分隔符为冒号
有时候学习脚本,你会发现sort命令后⾯跟了⼀堆类似-k1,2,或者-k1.2 -k3.4的东东,有些匪夷所思。

今天,我们就来搞定它—-k选项!
1、准备以下素材,test.txt 第⼀个域是公司名称,第⼆个域是公司⼈数,第三个域是员⼯平均⼯资,a.txt 和 b.txt :
1 [root@lzg ~]# cat test.txt
2 zaidu 2005000
3 guge 503000
4 sohu 804500
5 google 2105000
6 zdfg 150900
7 hyke 80800
8 [root@lzg ~]# cat a.txt
95 dsfsd 5000300
101 hyj 1000600
11156 efcv 4000700
1211 ghjty 800500
1323 rfdfg 600500
14256 hjtf 4000230
15 [root@lzg ~]# cat b.txt
16 dc:30:1.6:df
17 ab:10:2.5:1c
18 4f:50:3.3:d6
19 dd:20:4.2:8a
20 bb:10:2.5:f1
21 5e:80:5.4:e3
22 6e:60:5.1:ad
23 [root@lzg ~]#
2、让 test.txt 按公司的字母顺序排序,也就是按第⼀个域进⾏排序:(这个test.txt⽂件有三个域)
1 [root@lzg ~]# sort test.txt #默认按照升序⾃动排序
2 google 2105000
3 guge 503000
4 hyke 80800
5 sohu 804500
6 zaidu 2005000
7 zdfg 150900
8或者
9 [root@lzg ~]# sort -t'' -k1 test.txt #-t' '指定栏位分隔符为空格,-k1指定需要排序的栏位是1栏位
10 google 2105000
11 guge 503000
12 hyke 80800
13 sohu 804500
14 zaidu 2005000
15 zdfg 150900
16或者
17 [root@lzg ~]# sort -t '' -k 1 test.txt #-t和-k的可以⽤空格分开
18 google 2105000
19 guge 503000
20 hyke 80800
21 sohu 804500
22 zaidu 2005000
23 zdfg 150900
24 [root@lzg ~]#
以上开头是以字母开始的,如果是数字呢?
1 [root@lzg ~]# sort a.txt
211 ghjty 800500
3156 efcv 4000700
41 hyj 1000600
523 rfdfg 600500
6256 hjtf 4000230
75 dsfsd 5000300
8 [root@lzg ~]# sort -t'' -k1 a.txt #此处不加-t' '也可以,因为排序的是第⼀个域,如果是后⾯的,需要加
911 ghjty 800500
10156 efcv 4000700
111 hyj 1000600
1223 rfdfg 600500
13256 hjtf 4000230
145 dsfsd 5000300
15 [root@lzg ~]#
以上可以看到数字排序不是按照正常数值⼤⼩的⽅式排序的,⽽是按照⾸字符的⼤⼩排序,那这种情况怎么办呢?请看下⾯的⽅式
1 [root@lzg ~]# sort -n a.txt
21 hyj 1000600
35 dsfsd 5000300
411 ghjty 800500
523 rfdfg 600500
6156 efcv 4000700
7256 hjtf 4000230
8 [root@lzg ~]# sort -k1n a.txt #标准写法
91 hyj 1000600
105 dsfsd 5000300
1111 ghjty 800500
1223 rfdfg 600500
13156 efcv 4000700
14256 hjtf 4000230
1 [root@lzg ~]# sort -k3n a.txt
223 rfdfg 600500
311 ghjty 800500
41 hyj 1000600
5156 efcv 4000700
6256 hjtf 4000230
75 dsfsd 5000300
8 [root@lzg ~]# sort -t'' -k3n a.txt
911 ghjty 800500
10156 efcv 4000700
111 hyj 1000600
1223 rfdfg 600500
135 dsfsd 5000300
14256 hjtf 4000230
15 [root@lzg ~]#
以上可以看到⽤空格隔开的不加 -t' ' 也可以。

注意:空格的需要加单引号 '' ,其他类型的可不加,但最好是加单引号,看下⾯的例⼦:
1 [root@lzg ~]# sort -t: -k2n b.txt
2 ab:10:2.5:1c
3 bb:10:2.5:f1
4 dd:20:4.2:8a
5 dc:30:1.6:df
6 4f:50:3.3:d6
7 6e:60:5.1:ad
8 5e:80:5.4:e3
9 [root@lzg ~]# sort -t':' -k2n b.txt
10 ab:10:2.5:1c
11 bb:10:2.5:f1
12 dd:20:4.2:8a
13 dc:30:1.6:df
14 4f:50:3.3:d6
15 6e:60:5.1:ad
16 5e:80:5.4:e3
17 [root@lzg ~]#
3、我想让 test.txt 按照公司⼈数排序:
1 [root@lzg ~]# sort -t'' -k2n test.txt
2 guge 503000
3 hyke 80800
4 sohu 804500
5 zdfg 150900
6 zaidu 2005000
7 google 2105000
8 [root@lzg ~]#
此处出现⼀个问题,那就是hyke和sohu的公司⼈数相同,这个时候怎么办呢?按照默认规矩,是从第⼀个域开始进⾏升序排序,因此hyke排在了sohu前⾯。

4、我想让 test.txt 按照公司⼈数排序,⼈数相同的按照员⼯平均⼯资升序排序:
1 [root@lzg ~]# sort -t'' -k2n -k3n test.txt
2 guge 503000
3 hyke 80800
4 sohu 804500
5 zdfg 150900
6 zaidu 2005000
7 google 2105000
8 [root@lzg ~]#
加了⼀个-k2 -k3就解决了问题。

sort⽀持这种设定,就是说设定域排序的优先级,先以第2个域进⾏排序,如果相同,再以第3个域进⾏排序。

(如果你愿意,可以⼀直这么写下去,设定很多个排序优先级)
5、我想让 test.txt 按照员⼯⼯资降序排序,如果员⼯⼯资相同的,则按照公司⼈数升序排序:
1 [root@lzg ~]# sort -t'' -k3nr -k2n test.txt #n必须要跟在-k的后⾯
2 zaidu 2005000
3 google 2105000
4 sohu 804500
5 guge 503000
6 zdfg 150900
7 hyke 80800
8 [root@lzg ~]#
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(零),也是表⽰结尾到“域尾”。

7、test.txt 从公司英⽂名称的第⼆个字母开始进⾏排序:
1 [root@lzg ~]# sort -t'' -k1.
2 test.txt
2 zaidu 2005000
3 zdfg 150900
4 sohu 804500
5 google 2105000
6 guge 503000
7 hyke 80800
8 [root@lzg ~]#
使⽤ -k 1.2,这就表⽰从第⼀个域的第⼆个字符开始到本域的最后⼀个字符为⽌的字符串进⾏排序。

你会发现zaid因为第⼆个字母是a⽽名列榜⾸。

sohu和 google第⼆个字符都
是o,但sohu的h在google的o前⾯,所以sohu排在googl的前⾯。

8、只针对公司英⽂名称的第⼆个字母进⾏排序,如果相同的按照员⼯⼯资进⾏降序排序:
1 [root@lzg ~]# sort -t'' -k1.2,1.
2 -k3,3nr test.txt
2 zaidu 2005000
3 zdfg 150900
4 google 2105000
5 sohu 804500
6 guge 503000
7 hyke 80800
8 [root@lzg ~]#
由于只对第⼆个字母进⾏排序,所以我们使⽤了-k 1.2,1.2的表⽰⽅式,表⽰我们“只”对第⼆个字母进⾏排序。

(如果你问“我使⽤-k 1.2怎么不⾏?”,当然不⾏,因为你省略了End部分,这就意味着你将对从第⼆个字母起到本域最后⼀个字符为⽌的字9、在modifier部分还可以⽤到哪些选项?
可以⽤到b、d、f、i、n 或 r。

其中n和r你肯定已经很熟悉了。

b表⽰忽略本域的签到空⽩符号。

d表⽰对本域按照字典顺序排序(即,只考虑空⽩和字母)。

f表⽰对本域忽略⼤⼩写进⾏排序。

10、关于-k和-u联合使⽤的例⼦:
1 [root@lzg ~]# cat face.txt
2 google 1105000
3 baidu 1005000
4 guge 503000
5 sohu 1004500
6 [root@lzg ~]# sort -t'' -k2n face.txt
7 guge 503000
8 baidu 1005000
9 sohu 1004500
10 google 1105000
11 [root@lzg ~]# sort -t'' -k2n -u face.txt
12 guge 503000
13 baidu 1005000
14 google 1105000
15 [root@lzg ~]#
当设定以公司员⼯域进⾏数值排序,然后加-u后,sohu⼀⾏就被删除了!原来-u只识别⽤-k设定的域,发现相同,就将后续相同的⾏都删除。

1 [root@lzg ~]# sort -k1.1,1.1 -u face.txt
2 baidu 1005000
3 google 1105000
4 sohu 1004500
5 [root@lzg ~]#
这个例⼦也同理,开头字符是g的guge就没有幸免于难。

1 [root@lzg ~]# sort -n -k
2 -k
3 -u face.txt
2 guge 503000
3 sohu 1004500
4 baidu 1005000
5 google 1105000
6 [root@lzg ~]#
这⾥设置了两层排序优先级的情况下,使⽤-u就没有删除任何⾏。

原来-u是会权衡所有-k选项,将都相同的才会删除,只要其中有⼀级不同都不会轻易删除的
11、另类排序:
1 [root@lzg ~]# sort -n -k2.2,3.1 face.txt
2 guge 503000
3 baidu 1005000
4 sohu 1004500
5 google 1105000
6 [root@lzg ~]#
以第⼆个域的第⼆个字符开始到第三个域的第⼀个字符结束的部分进⾏排序。

第⼀⾏,会提取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前⾯了,⽤⼀个例⼦即可证明,如下:
1 [root@lzg ~]# sort -n -k2.2,3.1 -k1.1r face.txt
2 guge 503000
3 sohu 1004500
4 baidu 1005000
5 google 1105000
6 [root@lzg ~]#
其实上⾯的例⼦类似下⾯的例⼦:
1 [root@lzg ~]# sort -n -k2.2,3.1 face.txt
2 guge 503000
3 baidu 1005000
4 sohu 1004500
5 google 1105000
6 [root@lzg ~]# sort -n -k2.2 face.txt
7 guge 503000
8 baidu 1005000
9 sohu 1004500
10 google 1105000
11 [root@lzg ~]#
12、有时候在sort命令后会看到+1 -2这些符号,这是什么意思?
关于这种语法,最新的sort是这么进⾏解释的:
On older systems, `sort’ supports an obsolete origin-zero syntax `+POS1 [-POS2]‘ for specifying sort keys. POSIX 1003.1-2001 (*note Standards conformance::) does not allow this; use `-k’ instead.
原来,这种古⽼的表⽰⽅式已经被淘汰了,以后可以理直⽓壮的鄙视使⽤这种表⽰⽅法的脚本喽!
(为了防⽌古⽼脚本的存在,在这再说⼀下这种表⽰⽅法,加号表⽰Start部分,减号表⽰End部分。

最最重要的⼀点是,这种⽅式⽅法是从0开始计数的,以前所说的第⼀个域,在此被表⽰为第0个域。

以前的第2个字符,在此表⽰为第1个字符。

)。

相关文档
最新文档