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

【Linux】一步一步学Linux——sort命令(53)

程序员文章站 2024-02-23 23:38:46
...

00. 目录

01. 命令概述

sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。sort命令既可以从特定的文件,也可以从stdin中获取输入。

02. 命令格式

用法:sort [选项]... [文件]...

03. 常用选项

长选项必须使用的参数对于短选项时也是必需使用的。
排序选项:

  -b, --ignore-leading-blanks   忽略前导的空白区域
  -d, --dictionary-order        只考虑空白区域和字母字符
  -f, --ignore-case             忽略字母大小写
  -g, --general-numeric-sort    按照常规数值排序
  -i, --ignore-nonprinting      只排序可打印字符
  -M, --month-sort              比较 (未知) < "一月" < ... < "十二月"
                                在LC_ALL=C 时为(unknown) < `JAN' < ... < `DEC'
  -h, --human-numeric-sort    使用易读性数字(例如: 2K 1G)
  -n, --numeric-sort            根据字符串数值比较
  -R, --random-sort             根据随机hash 排序
      --random-source=文件      从指定文件中获得随机字节
  -r, --reverse                 逆序输出排序结果
      --sort=WORD               按照WORD 指定的格式排序:
                                        一般数字-g,高可读性-h,月份-M,数字-n,
                                        随机-R,版本-V
  -V, --version-sort            在文本内进行自然版本排序

其他选项:

      --batch-size=NMERGE       一次最多合并NMERGE 个输入;如果输入更多
                                        则使用临时文件
  -c, --check, --check=diagnose-first   检查输入是否已排序,若已有序则不进行操作
  -C, --check=quiet, --check=silent     类似-c,但不报告第一个无序行
      --compress-program=程序   使用指定程序压缩临时文件;使用该程序
                                        的-d 参数解压缩文件
      --debug                   为用于排序的行添加注释,并将有可能有问题的
                                        用法输出到标准错误输出
      --files0-from=文件        从指定文件读取以NUL 终止的名称,如果该文件被
                                        指定为"-"则从标准输入读文件名
  -k, --key=位置1[,位置2]       在位置1 开始一个key,在位置2 终止(默认为行尾)
                                参看POS 语法。
  -m, --merge                   合并已排序的文件,不再进行排序
  -o, --output=文件             将结果写入到文件而非标准输出
  -s, --stable                  禁用last-resort 比较以稳定比较算法
  -S, --buffer-size=大小        指定主内存缓存大小
  -t, --field-separator=分隔符  使用指定的分隔符代替非空格到空格的转换
  -T, --temporary-directory=目录        使用指定目录而非$TMPDIR 或/tmp 作为
                                        临时目录,可用多个选项指定多个目录
      --parallel=N              将同时运行的排序数改变为N
  -u, --unique          配合-c,严格校验排序;不配合-c,则只输出一次排序结果
  -z, --zero-terminated 以0 字节而非新行作为行尾标志
      --help            显示此帮助信息并退出
      --version         显示版本信息并退出

POS 是F[.C][OPTS],F 代表域编号,C 是域中字母的位置,F 和C 均从1开始计数
如果没有有效的-t 或-b 选项存在,则从前导空格后开始计数字符。OPTS 是一个或多个
由单个字母表示的顺序选项,以此覆盖此key 的全局顺序设置。如果没有指定key 则
将其整个行。

指定的大小可以使用以下单位之一:
内存使用率% 1%,b 1、K 1024 (默认),M、G、T、P、E、Z、Y 等依此类推。

如果不指定文件,或者文件为"-",则从标准输入读取数据。

04. 参考示例

4.1 将文本默认排序

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

[[email protected] test]$ cat txt
aaa:10:1.1
ccc:30:3.3
ddd:40:4.4
bbb:20:2.2
eee:50:5.5
eee:50:5.5
[[email protected] test]$ sort txt
aaa:10:1.1
bbb:20:2.2
ccc:30:3.3
ddd:40:4.4
eee:50:5.5
eee:50:5.5
[[email protected] test]$ 

4.2 忽略相同行

[[email protected] test]$ sort  -u txt
aaa:10:1.1
bbb:20:2.2
ccc:30:3.3
ddd:40:4.4
eee:50:5.5
[[email protected] test]$ 

4.3 忽略每行前面开始出的空格字符

[[email protected] test]$ sort -b txt
 aaa:10:1.1
bbb:20:2.2
ccc:30:3.3
ddd:40:4.4
eee:50:5.5
eee:50:5.5
[[email protected] test]$ 

4.4 检查文件是否已经按照顺序排序

[[email protected] test]$ sort -c txt
sort:txt:4:无序: bbb:20:2.2
[[email protected] test]$ 

4.5 将第2列按照数字从小到大顺序排列

-n是按照数字大小排序,-r是以相反顺序,-k是指定需要爱排序的栏位,-t指定栏位分隔符为冒号

[[email protected] test]$ cat txt
AAA:BB:CC
aaa:30:1.6
ccc:50:3.3
ddd:20:4.2
bbb:10:2.5
eee:40:5.4
eee:60:5.1
[[email protected] test]$ sort -t: -nk 2 txt
AAA:BB:CC
bbb:10:2.5
ddd:20:4.2
aaa:30:1.6
eee:40:5.4
ccc:50:3.3
eee:60:5.1
[[email protected] test]$ 

4.6 将第3列数字从大到小顺序排列

-n是按照数字大小排序,-r是以相反顺序,-k是指定需要爱排序的栏位,-t指定栏位分隔符为冒号

[[email protected] test]$ sort  -t: -n -r -k 3 txt
eee:40:5.4
eee:60:5.1
ddd:20:4.2
ccc:50:3.3
bbb:10:2.5
aaa:30:1.6
AAA:BB:CC
[[email protected] test]$ 

4.7 将排序结果输出到源文件

[[email protected] test]$ sort txt -o sort.txt
[[email protected] test]$ cat sort.txt 
aaa:30:1.6
AAA:BB:CC
bbb:10:2.5
ccc:50:3.3
ddd:20:4.2
eee:40:5.4
eee:60:5.1
[[email protected] test]$ 

4.8 按照数值的大小排序

[[email protected] test]$ cat txt
1
10
19
11
2
5

//默认按照字符串排序的结果
[[email protected] test]$ sort txt
1
10
11
19
2
5

//按照数值大小排序结果
[[email protected] test]$ sort -n txt
1
2
5
10
11
19
[[email protected] test]$ 

4.9 -k选项的语法格式

-k选项的语法格式

FStart.CStart Modifie,FEnd.CEnd Modifier
-------Start--------,-------End--------
 FStart.CStart 选项  ,  FEnd.CEnd 选项

这个语法格式可以被其中的逗号,分为两大部分,Start部分和End部分。Start部分也由三部分组成,其中的Modifier部分就是我们之前说过的类似n和r的选项部分。我们重点说说Start部分的FStartC.StartC.Start也是可以省略的,省略的话就表示从本域的开头部分开始。FStart.CStart,其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。同理,在End部分中,你可以设定FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将CEnd设定为0(零),也是表示结尾到“域尾”。

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

[[email protected] test]$ sort -t ' ' -k 1.2 txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
[[email protected] test]$ 

使用了-k 1.2,表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序。你会发现baidu因为第二个字母是a而名列榜首。sohu和 google第二个字符都是o,但sohu的h在google的o前面,所以两者分别排在第二和第三。guge只能屈居第四了

只针对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行降序排序

[[email protected] test]$ sort -t: -k 1.2,1.2 -nrk 3,3 txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

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

4.10 sort其它选项

[[email protected] test]$ cat txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
[[email protected] test]$ 

第一个域是公司名称,第二个域是公司人数,第三个域是员工平均工资。

公司的字母顺序排序

[[email protected] test]$ sort -t ' ' -k 1 txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
[[email protected] test]$ 

按照公司人数排序

[[email protected] test]$ sort -t ' ' -n -k 2 txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

不用解释,我相信你能懂。但是,此处出现了问题,那就是baidu和sohu的公司人数相同,都是100人,这个时候怎么办呢?按照默认规矩,是从第一个域开始进行升序排序,因此baidu排在了sohu前面。

按照公司人数排序 ,人数相同的按照员工平均工资升序排序

[[email protected] test]$ sort -t ' ' -n -k 2 -k 3 txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
[[email protected] test]$ 

看,我们加了一个-k2 -k3就解决了问题。对滴,sort支持这种设定,就是说设定域排序的优先级,先以第2个域进行排序,如果相同,再以第3个域进行排序。(如果你愿意,可以一直这么写下去,设定很多个排序优先级)

按照员工工资降序排序,如果员工人数相同的,则按照公司人数升序排序

[[email protected] test]$ sort -n -t ' ' -k 3r -k 2 txt 
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
[[email protected] test]$ 

此处有使用了一些小技巧,你仔细看看,在-k 3后面偷偷加上了一个小写字母r。揭晓:r和-r选项的作用是一样的,就是表示逆序。因为sort默认是按照升序排序的,所以此处需要加上r表示第三个域(员工平均工资)是按照降序排序。此处你还可以加上n,就表示对这个域进行排序时,要按照数值大小进行排序,举个例子吧:

[[email protected] test]$ sort -t ' ' -k 3nr -k 2n txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
[[email protected] test]$ 

我们去掉了最前面的-n选项,而是将它加入到了每一个-k选项中了。

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

[[email protected] test]$ sort -t ' ' -k 1.2 txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
[[email protected] test]$ 

对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行降序排序

[[email protected] test]$ sort -t ' ' -k 1.2,1.2 -k 3,3nr txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
[[email protected] test]$ 

05. 附录

参考:【Linux】一步一步学Linux系列教程汇总

上一篇: Tr A

下一篇: Python 处理Excel总结(1)