在处理请求或者日志文件等等,通过排序的方能使我们得到一个更加只管的输出。sort就是这么一个常用而又强大的工具。
sort是以行为单位,按照每一个字符的ACSII码来进行排序。sort的语法是:
sort [option]... [file]...
本文简述sort的几个常用操作,详细操作请man sort
。
常规操作
sort [-u][-r][-o][-n] [-k][-t] file
是不是看的眼花缭乱的,没关系我们一个一个来。
➜ shell cat sortTest.txt
d
c
b
a
➜ shell sort sortTest.txt
a
b
c
d
➜ shell
sort 去重
去重的意思就是去除相同行(仅保留一行),其实这是比较浅显的解释,sort在去重的时候会按照sort的规则去比较两行,如果发现在这个规则下相等,则去掉一行。sort默认的规则是从第一个字符到最后一个字符的比较。因此此可以去掉相同内容的行。
➜ shell cat sortTest.txt
d
c
c
c
b
a
a
➜ shell sort -u sortTest.txt
a
b
c
d
可以看到无论两行三行,都给我统统消失。
shell反向排序
之前我们介绍的sort功能都是按照ASCII的升序排列,如果使用-r选项,则可以按照其降序排列
➜ shell sort -ur sortTest.txt
d
c
b
a
sort输出
很容易理解,当我们需要将sort的结果输出到一个文件中时,我们通常会使用sort a.txt > b.txt
不过遗憾的是,不能够将排序后文件输出到原来的文件中:sort a.txt > a.txt
。sort -o 选项就应运而生了(不过很可惜这也是-o的唯一作用,个人感觉还是>
更好用)。
➜ shell sort -ur sortTest.txt
d
c
b
a
➜ shell sort -ur sortTest.txt > sortTest.txt
➜ shell cat sortTest.txt
直接使用>
可以看到文件将被清空。
➜ shell cat sortTest.txt
d
c
b
a
➜ shell sort -ur sortTest.txt -o sortTest.txt
➜ shell cat sortTest.txt
d
c
b
a
sort按照数字排序
很明显,仅仅是按照ASCII排序是远远不满足我们的需求,比如我们会遇到10<2的情况(这是什么原因呢?因为按照ascii比较,第一个字符小的就排在前面了):
➜ shell cat number.txt
10
2
➜ shell sort number.txt
10
2
下面我们按照数字来进行排序:
➜ shell sort -n number.txt
2
10
此时2排在了前面。
kt组合
通常来说-k -t 选项是一起操作的。
比如说我们有这样一个素材:
➜ shell cat score.txt
A:5:2
B:2:4
C:1:6
表示A、B、C对于PHP和C的使用频率。使用’:’分割。此时我们需要借助-k-t选项来进行排序。
其中-t用于指定分隔符,-k用于指定比较的列(是分割之后的列)
➜ shell sort -k 2 -t : score.txt
C:1:6
B:2:4
A:5:2
➜ shell sort -k 3 -t : score.txt
A:5:2
B:2:4
C:1:6
sort进阶操作
所谓进阶操作无非就是将普通操作细化,需要了解更多的规则,当然也可以满足更多的需求。
-k命令
-k命令我们之前提到是对列进行排序的约定。其实-k命令的完整语法是:
-k [ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
如果觉得混乱了,不要着急。慢慢解释。
在解释之前要记住:
- 没有设定End的时候,默认到行尾。
- 靠前的Fstar优先级高于靠后的。
我们都知道-k和-t是配合使用的。我们使用-t来分割每一行得到的各个小部分我们称为一个域(field)。
所以,FStar表示的是选择哪个域。在一个域中,我们需要考虑从哪个元素开始,至哪个元素结束,这就是CStart。通过指定开始和结束的元素就可以指定我们排序的区域。
modifier表示,我们排序后的一个操作,r,u等等。
比如:仅仅使用第一个域的第一个元素排序:
sort -k 1.1,1.1 -t ' ' file
第一个域的第一个元素到第一个域的第三个元素,如果相同。按照第二个域第一个元素排序
sort -k 1.1,1.3 -k 2.1,2.1 -t ' ' file
例子:
原始材料:
➜ shell cat company.txt
facebook 1300 4000
linkedIn 2000 5433
amazon 1200 3900
apple 3000 7000
google 3000 6667
本人伪造了一些公司的资料,分别表示公司名字,员工数量,工资。
下面按照公司名字的第二个字母排序:
➜ shell sort -k 1.2 -t ' ' company.txt
facebook 1300 4000
linkedIn 2000 5433
amazon 1200 3900
google 3000 6667
apple 3000 7000
可以看到facebook排到了第一。
下面我们按照公司名称的第一个字母排序,如果遇到相同的就按照员工数量排序:
➜ shell sort -t ' ' -k 1.1,1.1 -k 3nr company.txt
apple 3000 7000
amazon 1200 3900
facebook 1300 4000
google 3000 6667
linkedIn 2000 5433