Linux sort 命令的使用

sort 的工作原理:

目录

sort 的工作原理:

-u 选项:在输出中去除重复行

-r 选项:sort默认的排序方式是升序,如果想改成降序,加个 -r 就行了。

-o选项:用排序后的结果替换原文件的内容

-n 选项:告诉 sort 以数值大小来排序

-t 选项:后面可以设定间隔符,对每行内容进行切割,

-k选项:用来说明按照第几列来进行排序

-c 选项:会检查文件是否已排好序,如果乱序,则输出第一个乱序的行的相关信息,最后返回1(乱序返回1,顺序(升序)返回 0)。

-C选项:会检查文件是否已排好序,如果乱序,不输出内容,仅返回1。

-k 选项的复杂用法

-k 选项的具体语法格式:

-k 与 -u 的联合使用


sort 将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按 ASCII 码值进行比较,最后将他们按升序输出。

例一:

[root@localhost gcx]# cat a
banana
apple
pear
orange
pear
[root@localhost gcx]# sort a
apple
banana
orange
pear
pear
[root@localhost gcx]#

-u 选项:在输出中去除重复行

例二:

[root@localhost gcx]# cat a
banana
apple
pear
orange
pear
[root@localhost gcx]# sort -u a
apple
banana
orange
pear
[root@localhost gcx]#

pear 由于重复被 -u 删除了

-r 选项:sort默认的排序方式是升序,如果想改成降序,加个 -r 就行了。

例三:

[root@localhost gcx]# cat a
2
6
4
3
[root@localhost gcx]# sort a
2
3
4
6
[root@localhost gcx]# sort -r a
6
4
3
2

-o选项:用排序后的结果替换原文件的内容

由于 sort 默认是把结果输出到标准输出,所以需要用重定向才能将结果写入到文件,形如 sort filename > new.file。

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

例四:

[root@localhost gcx]# cat b
banana
apple
pear
orange
[root@localhost gcx]# sort b > b
[root@localhost gcx]# cat b
[root@localhost gcx]#

看,文件 b 被清空了 !!!

这时 -o 选项应运而生,它成功的解决

了这个问题,可以让你放心的把排序后的结果写入到原文件

例五:

[root@localhost gcx]# cat b
banana
apple
pear
orange
[root@localhost gcx]# sort -r b -o b
[root@localhost gcx]# cat b
pear
orange
banana
apple
[root@localhost gcx]#

-n 选项:告诉 sort 以数值大小来排序

你有没有遇到过 10 比 2小的情况?出现这种情况是由于排序程序将这些数字按字符来排序了,排序程序会先比较 1 和 2,显然 1 小,所以10就出现在了 2 的前面

例六:

[root@localhost gcx]# cat c
1
14
10
2
24
5
[root@localhost gcx]# sort c
1
10
14
2
24
5
[root@localhost gcx]# sort -n c
1
2
5
10
14
24
[root@localhost gcx]# sort -nr c
24
14
10
5
2
1
[root@localhost gcx]#

-t 选项:后面可以设定间隔符,对每行内容进行切割,

-k选项:用来说明按照第几列来进行排序

[root@localhost gcx]# cat a

banana:30:5.5

apple:10:2.5

pear:90:2.3

orange:20:3.4

这个文件有三列,列与列之间用冒号隔开了,第一列表示水果类型,第二列表示水果数量,第三列表示价格。

我如果想以水果数量,即第二列来排序,如何使用 sort 呢?

例七:

[root@localhost gcx]# sort -t: -n -k2 a
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3
[root@localhost gcx]#

 

如果没有设置 -t 参数,那么就默认以空白符作为切割符:

例八:

[root@localhost gcx]# cat c
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
[root@localhost gcx]# sort -n -k2 -k3  c
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
[root@localhost gcx]# cat d
google:110:5000
baidu:100:5000
guge:50:3000
sohu:100:4500
[root@localhost gcx]# sort -n -k2 -k3  d   # 可以发现 -k 选项的设定根本没有发挥作用,因为此时第二个域、第三个域全为空,sort按照第一个域进行排序
baidu:100:5000
google:110:5000
guge:50:3000
sohu:100:4500

-c 选项:会检查文件是否已排好序,如果乱序,则输出第一个乱序的行的相关信息,最后返回1(乱序返回1,顺序(升序)返回 0)。

-C选项:会检查文件是否已排好序,如果乱序,不输出内容,仅返回1。

例九:

[root@localhost gcx]# cat a
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4
[root@localhost gcx]# sort -c a
sort: a:2: disorder: apple:10:2.5   # a文件第二行乱序
[root@localhost gcx]# echo $?
1
[root@localhost gcx]# cat a
apple:10:2.5
banana:30:5.5
pear:90:2.3
orange:20:3.4
[root@localhost gcx]# sort -c a
sort: a:4: disorder: orange:20:3.4  # a文件第四行乱序
[root@localhost gcx]# echo $?
1
[root@localhost gcx]# sort a -o a
[root@localhost gcx]# sort -c a
[root@localhost gcx]# echo $?
0 
[root@localhost gcx]# sort -r a -o a   # 倒序排列视为乱序
[root@localhost gcx]# cat a
pear:90:2.3
orange:20:3.4
banana:30:5.5
apple:10:2.5
[root@localhost gcx]# sort -c a  
sort: a:2: disorder: orange:20:3.4
[root@localhost gcx]# echo $?
1
[root@localhost gcx]# sort a -o a
[root@localhost gcx]# sort -c a
[root@localhost gcx]# echo $?
0
[root@localhost gcx]# cat a
pear:90:2.3
orange:20:3.4
banana:30:5.5
apple:10:2.5
[root@localhost gcx]# sort -C a   # 大 C 没有提示信息
[root@localhost gcx]# echo $?
1
[root@localhost gcx]#

-k 选项的复杂用法

[root@localhost gcx]# cat c

google 110 5000

baidu 100 5000

guge 50 3000

sohu 100 4500

第一列:公司名称,第二列:公司人数,第三列:工资

例十:按照公司名称进行排序

[root@localhost gcx]# sort -t' ' -k1 c
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
[root@localhost gcx]#

 例十一:按照公司人数进行排序

[root@localhost gcx]# sort -n -t' ' -k2 c
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
[root@localhost gcx]#

注意:此时 baidu 和 sohu 公司人数相同,都是100人,这个时候sort是怎么排序的呢?按照默认规矩,是从第一个域开始进行升序排序,因此 baidu 排在了 sohu 前面。

例十二:按照公司人数排序,人数相同的按照工资升序排序

[root@localhost gcx]# sort -n -t' ' -k2 -k3 c
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
[root@localhost gcx]#

此时 sohu 排在了 baidu 的前面!

sort 支持这种设定,设定域排序的优先级,先以第二个域进行排序,如果相同,再以第三个域进行排序,如果你愿意,可以一直这样写下去。。。

例十三:按照工资降序排序,如果员工人数相同,则按照公司人数升序排序

[root@localhost gcx]# sort -n -t' ' -k3r -k2 c
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
[root@localhost gcx]#

sort 默认是按照升序排序的,在第三个域后面加上 r 表示对这个域降序排列。

不过要注意 r 参数的位置!!!

例十四:

[root@localhost gcx]# sort -n -t' ' -rk3 -k2 c
google 110 5000
baidu 100 5000
sohu 100 4500
guge 50 3000
[root@localhost gcx]#

r 放到了 k 前面 ,发现 k3 和  k2 都变成了降序!!

你也可以把前面的 n 去掉,加入每个域中

例十五:

[root@localhost gcx]# sort -t' ' -k3nr -k2n c
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
[root@localhost gcx]#

-k 选项的具体语法格式:

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

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

如果不设定 End 部分,那么就认为 End 被设定为行尾。

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

Cstart 也是可以省略的,省略的话就表示从本域的开头部分开始。-k2 、-k3 就是省略了 Cstart 的例子。

Fstart 就是表示使用的域,而 Cstart 则表示在 Fstart 域中从第几个字符开始算“排序首字符”

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

总而言之:这个语法定义了第几个域的第几个字符为排序首字符(FStart.CStart),到第几个域的第几个字符为排序末字符(FEnd.CEnd)

例十六:从公司英文名称的第二个字母开始进行排序:

[root@localhost gcx]# sort -t' ' -k1.2 c
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
[root@localhost gcx]#

这里我们使用了 -k1.2, 表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序

例十七:只针对公司名称的第二个字母进行排序,如果相同则按照工资进行降序排序

[root@localhost gcx]# sort -t' ' -k1.2,1.2 -k3nr c
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
[root@localhost gcx]#

如果我们仅使用 -k1.2 是不符合要求的,因为你省略了 End 部分,这意味着你将对从第二个字母到本域最后一个字符为止的字符串进行排序。

例十八:-k 跨域排序的假象:

[root@localhost gcx]# cat c
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
[root@localhost gcx]# sort -n -k2.2,3.1 c
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
[root@localhost gcx]#

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

第一行会取: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 就自动比较第一个域去了!

-k 与 -u 的联合使用

例十九:

[root@localhost gcx]# cat c
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
[root@localhost gcx]# sort -n -k2 c
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
[root@localhost gcx]# sort -n -k2 -u c
guge 50 3000
baidu 100 5000
google 110 5000
[root@localhost gcx]#

当设定以公司人数域进行数值排序,然后加 -u 后,sohu 一行就被删除了!原来 -u 值识别用 -k 设定的域,发现相同,就将后续相同行都删除。

例二十:

[root@localhost gcx]# sort -k1 -u c
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
[root@localhost gcx]# sort -k1.1,1.1 -u c
baidu 100 5000
google 110 5000
sohu 100 4500
[root@localhost gcx]#

开头字符是 g 的 guge 被删除了!

例二十一:

[root@localhost gcx]# sort -n -k2 -k3 -u c
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
[root@localhost gcx]#

这里设置了两层排序优先级的情况下,使用 -u 就没有删除任何行,原来 -u 是会权衡所有 -k 选项,都相同才会删除,只有其中一个相同是不会随便删除的!

上一篇:HTML5 Canvas 绘图入门


下一篇:阶段9反射