欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux sort 命令的使用

程序员文章站 2022-04-30 23:12:13
...

sort 的工作原理:

目录

sort 的工作原理:

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

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

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

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

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

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

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

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

-k 选项的复杂用法

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

-k 与 -u 的联合使用


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

例一:

[[email protected] gcx]# cat a
banana
apple
pear
orange
pear
[[email protected] gcx]# sort a
apple
banana
orange
pear
pear
[[email protected] gcx]#

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

例二:

[[email protected] gcx]# cat a
banana
apple
pear
orange
pear
[[email protected] gcx]# sort -u a
apple
banana
orange
pear
[[email protected] gcx]#

pear 由于重复被 -u 删除了

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

例三:

[[email protected] gcx]# cat a
2
6
4
3
[[email protected] gcx]# sort a
2
3
4
6
[[email protected] gcx]# sort -r a
6
4
3
2

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

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

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

例四:

[[email protected] gcx]# cat b
banana
apple
pear
orange
[[email protected] gcx]# sort b > b
[[email protected] gcx]# cat b
[[email protected] gcx]#

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

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

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

例五:

[[email protected] gcx]# cat b
banana
apple
pear
orange
[[email protected] gcx]# sort -r b -o b
[[email protected] gcx]# cat b
pear
orange
banana
apple
[[email protected] gcx]#

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

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

例六:

[[email protected] gcx]# cat c
1
14
10
2
24
5
[[email protected] gcx]# sort c
1
10
14
2
24
5
[[email protected] gcx]# sort -n c
1
2
5
10
14
24
[[email protected] gcx]# sort -nr c
24
14
10
5
2
1
[[email protected] gcx]#

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

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

[[email protected] gcx]# cat a

banana:30:5.5

apple:10:2.5

pear:90:2.3

orange:20:3.4

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

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

例七:

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

 

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

例八:

[[email protected] gcx]# cat c
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
[[email protected] gcx]# sort -n -k2 -k3  c
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
[[email protected] gcx]# cat d
google:110:5000
baidu:100:5000
guge:50:3000
sohu:100:4500
[[email protected] 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。

例九:

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

-k 选项的复杂用法

[[email protected] gcx]# cat c

google 110 5000

baidu 100 5000

guge 50 3000

sohu 100 4500

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

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

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

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

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

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

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

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

此时 sohu 排在了 baidu 的前面!

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

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

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

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

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

例十四:

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

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

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

例十五:

[[email protected] gcx]# sort -t' ' -k3nr -k2n c
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
[[email protected] 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)

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

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

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

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

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

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

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

[[email protected] gcx]# cat c
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
[[email protected] gcx]# sort -n -k2.2,3.1 c
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
[[email protected] 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 的联合使用

例十九:

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

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

例二十:

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

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

例二十一:

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

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

相关标签: Shell Script