Linux sort命令

Linux 命令大全

Linux sort命令用于将文本文件内容加以排序。

sort可针对文本文件的内容,以行为单位来排序。

语法

sort [-bcdfimMnr][-o<输出文件>][-t<分隔字符>][+<起始栏位>-<结束栏位>][--help][--verison][文件]

参数说明

linux中通过vim命令创建一个文件名为 's_sort.txt'

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# vim s_sort.txt

通过cat查看文件 's_sort.txt'内容如下:

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# cat s_sort.txt 
1 一
2 二
3 三
3 三
6 六
5 五
4 四

sort的工作原理

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

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort s_sort.txt 
1 一
2 二
3 三
3 三
4 四
5 五
6 六

sort的-r选项降序排序

前面的sort实例是一个按升序排序,现在期望通过sort降序排序如何解决呢?

很简单加一个参数 -r

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -r s_sort.txt 
6 六
5 五
4 四
3 三
3 三
2 二
1 一

sort的-u选项 去重

我们发现上面的sort实例中,'3 三' 这条数据是重复的,我们现在解决去重问题

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -u s_sort.txt 
1 一
2 二
3 三
4 四
5 五
6 六

sort的-o选项 将排序的结果保存到文件中

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

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -u s_sort.txt > temp.txt
[root@iz8vbbxoyfcgyzkxcspg04z mnt]# cat temp.txt
1 一
2 二
3 三
4 四
5 五
6 六

如果你想把排序结果输出到原文件中,不用-o参数,用重定向结果将是空

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -u s_sort.txt > s_sort.txt 
[root@iz8vbbxoyfcgyzkxcspg04z mnt]# cat s_sort.txt 
[root@iz8vbbxoyfcgyzkxcspg04z mnt]#

我们发现,s_sort.txt文件的内容清空了。

如果想输出到原文件只能用,-o选项,它可以成功的解决了重新排序内容清空的问题,可以放心的将结果写入原文件。

通过cp命令恢复数据:

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# cp temp.txt s_sort.txt 
cp: overwrite ‘s_sort.txt’? y
[root@iz8vbbxoyfcgyzkxcspg04z mnt]# cat s_sort.txt 
1 一
2 二
3 三
4 四
5 五
6 六
[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -r s_sort.txt -o s_sort.txt
[root@iz8vbbxoyfcgyzkxcspg04z mnt]# cat s_sort.txt 
6 六
5 五
4 四
3 三
2 二
1 一

sort的-n选项 使用数值排序

我们会发现有一个问题,数字在排序中跟我们想象的不一样,例如:我们再增加一条数据'11 十一' 

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort  s_sort.txt
11 十一
1 一
2 二
3 三
4 四
5 五
6 六

什么情况,升序怎么11还在1的前面呢?应该排在最后才合适呀?因为sort排序默认是按照ASCII码值进行比较的1的ASCII码值小于空格,所以就出现了我们不想看到的结果。如何解决呢?带上 -n 参数即可。

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -n  s_sort.txt
1 一
2 二
3 三
4 四
5 五
6 六
11 十一

sort的-t选项和-k选项 配合使用可以对某一字段进行排序

假如有一个文件的内容如下:

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# cat web.txt
baidu.com:10:13
taobao.com:10:10
xinbiancheng.cn:100:20
google.cn:20:10

这个文件有三列,列与列之间用冒号隔开了,第一列表示网站,第二列表示点击次数,第三列表示人数。

如果想以点击次数来排序,也就是以第二列来排序,如何利用sort实现?

sort提供了-t选项,设定间隔符。(跟 cutpaste的-d选项 用法相同)

指定了间隔符之后,就可以用-k来指定某列进行排序了。

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -t ':' -n -k 2  web.txt
baidu.com:10:13
taobao.com:10:10
google.cn:20:10
xinbiancheng.cn:100:20

在网上看到sort 有 -k1,2 或者-k1.2 -k3.4这样的参数,有些匪夷所思,在这里就分享给大家。

sort -k选项 专讲

按照网站名字母顺序排序,也就是按第一个域进行排序:(这个web.txt文件有三个域)

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -t ':' -k 1 web.txt
baidu.com:10:13
google.cn:20:10
taobao.com:10:10
xinbiancheng.cn:100:20

期望通过 sort 对web.txt按照网站的点击次数进行倒序排序

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -t  ':' -k 2nr web.txt
xinbiancheng.cn:100:20
google.cn:20:10
baidu.com:10:13
taobao.com:10:10

参数解释说明:-t 进行分割字段, -k 对那个字段进行排序,2nr 代表的是第2个字段,n是数值排序,r是降序。

现实中期望点击次数多,使用人数少,所以使用下面的案例

期望通过 sort 对web.txt点击次数为降序,人数为升序

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -t  ':' -k 2nr -k 3n web.txt
xinbiancheng.cn:100:20
google.cn:20:10
taobao.com:10:10
baidu.com:10:13

要继续往下深入的话,就不得不来点理论知识。你需要了解-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(零),也是表示结尾到“域尾”。

sort只对网站的第二个字母进行排序,如果相同的人数进行降序排序:

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# sort -t  ':' -k 1.2,1.2 -k 3,3nr web.txt
baidu.com:10:13
taobao.com:10:10
xinbiancheng.cn:100:20
google.cn:20:10

由于只对第二个字母进行排序,所以我们使用了-k 1.2,1.2的表示方式,表示我们“只”对第二个字母进行排序。(如果您问“使用-k 1.2怎么不行?”,当然不行,因为你省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序)。对于人数进行排序,我们也使用了-k 3,3,这是最准确的表述,表示我们“只”对本域进行排序,因为如果你省略了后面的3,就变成了我们“对第3个域开始到最后一个域位置的内容进行排序”了。

sort其它常见用法

通过sort查看系统进程中,内存占用最多的前5个进程信息

[root@iz8vbbxoyfcgyzkxcspg04z mnt]# ps aux|sort -gr -k 4|head -n 5

因是私密信息在这里就不显示结果了,自己复制命令执行即可。

Linux 命令大全