Linux文件排序工具 sort 命令详解

您所在的位置:网站首页 文件夹里的文件怎么自定义排序保存不了 Linux文件排序工具 sort 命令详解

Linux文件排序工具 sort 命令详解

2024-07-15 22:46| 来源: 网络整理| 查看: 265

sort是排序工具,它完美贯彻了Unix哲学:"只做一件事,并做到完美"。它的排序功能极强、极完整,只要文件中的数据足够规则,它几乎可以排出所有想要的排序结果,是一个非常优质的工具。

虽然sort很强大,但它的选项很少,使用方法也很简单。更让人觉得它成功的地方在于:即使想要实现复杂、完整的sort功能,所使用的选项和一般使用时的选项没什么不同。只不过要实现复杂功能时,必须得理解sort是如何工作的。

也就是说,没搞懂sort工作机制时,它也能完成任务,指哪就能打哪,但没被指到的地方难免会有所偏差和疑惑。只有搞懂了sort机制,才能真正的指哪打哪,结果中一丝偏差也没有,即使出现了偏差也知道是为什么。

本文先解释sort命令的常用选项,再给出sort的简单使用示例,用于初步解释sort各选项,最后对sort深入说明。更完整的选项说明可参考info sort的译文:sort命令中文手册(info sort翻译)。

 

1.1 选项说明

sort读取每一行输入,并按照指定的分隔符将每一行划分成多个字段,这些字段就是sort排序的对象。同时,sort可以指定按照何种排序规则进行排序,如按照当前字符集排序规则(这是默认排序规则)、按照字典排序规则、按照数值排序规则、按照月份排序规则、按照文件大小格式(k4000>300 ____ ^ no match for key ________________ 5>SUSE>4000>300 ____ ^ no match for key _______________

(5).在对第3列按数值排序规则排序的基础上,使用第2列作为决胜属性,且以默认排序规则对此列降序排序。

[root@linuxidc tmp]# sort -t $'\t' -k3n -k2r system.txt 6 Debian 600 200 4 linux 1000 200 3 bsd 1000 600 1 mac 2000 500 2 winxp 4000 300 5 SUSE 4000 300

由于既要对第3列按数值升序排序,又要对第2列按默认规则降序排序,因此只能对每个字段单独分配选项。注意,虽然"r"选项是降序结果,但它不影响排序过程,只影响最终排序结果。也就是说,在按照升序排序结束得到最终结果后,再反转第2列顺序,也就是得到了降序的结果。同样也说明,sort在排序的时候,一定且只能按照升序排序,只有排序动作结束了"r"选项才开始工作。

紧跟在字段后的选项(如"-k3n"的"n"和"-k2r"的"r")称为私有选项,使用短横线写在字段外的选项(如"-n"、"-r")为全局选项。当没有为字段分配私有选项时,该排序字段将继承全局选项。当然,只有像"-n"、"-r"这样的排序性的选项才能继承和分配给字段,"-t"这样的选项则无法分配。

因此,"-n -k3 -k4"、"-n -k3n -k4"和"-k3n -k4n"是等价的,"-r -k3n -k4"和"-k3nr -k4r"是等价的。

实际上,上面的命令写法并不严谨。更标准的写法应该如下:

sort -t $'\t' -k3n -k2,2r system.txt

"-k2,2"表示排序对象从第2个字段开始到第2个字段结束,也就是限定了只对第二个字段排序。它的格式为"POS1,POS2",如果省略POS2,将自动扩展到行尾,即"-k2"等价于"-k2,4",也就是说,对整个第2列到第4列进行排序。

需要注意,由于上面的"-k2"继承了全局默认的排序规则,即按字符排序而非按数值排序,此时它能够等价于"-k2,4",但如果是"-k2n"按照数值排序的话,它不等价于"-k2,4n"或"-k2n,4n"或"-k2n,4"(这3者为等价写法),之所以不等价,是因为按数值排序时只能识别数字和负号"-",当排序时遇到其他所有字符,都将立即结束此次排序。所以"-k2n"等价于"-k2,2n"或"-k2n,2"或"-k2n,2n"。

这些理论性的知识点,请参照下一小节sort的理论内容。后文也不再解释理论性的内容,只是介绍命令使用方法。

(6).在对第3列按数值排序规则排序的基础上,使用第2列的第2个字符作为决胜属性,且以默认排序规则对此列升序排序。

[root@linuxidc tmp]# sort -t $'\t' -k3n -k2.2,2.2 system.txt 6 Debian 600 200 4 linux 1000 200 3 bsd 1000 600 1 mac 2000 500 2 winxp 4000 300 5 SUSE 4000 300

其中"-k2.2,2.2"表示从第2个字段的第2个字符开始,到第2个字段的第2个字符结束,即严格限定为第2个字段第2个字符。如果需要对此字符降序排序,则"-k2.2,2.2r"。

(7).使用"-u"去除重复字段所在的行。例如第3列有两行1000,两行4000,去除字段重复的行时,将只保留排在前面的第一行。

[root@linuxidc tmp]# sort -t $'\t' -k3n -u system.txt 6 Debian 600 200 3 bsd 1000 600 1 mac 2000 500 2 winxp 4000 300

由于需要去除重复字段的行,因此使用"-u"时将禁止sort做"最后一次排序"。至于字段重复的行中,如何判断哪一行是排在最前面的行,需要搞懂sort的整个工作机制,请通读本文。

"sort -u"和"sort | uniq"是等价的,但是如果多指定几个选项,它们将不等价。例如,"sort -n -u"只会检查排序字段数值部分的唯一性,但"sort -n | uniq"在sort对行中字段按数值排序后,uniq将检查整个行的唯一性。

(8).将排序结果保存到文件中。即可以使用重定向,也可以使用"-o"选项,但使用重定向不可保存到原文件,因为在sort开始执行前,原文件先被重定向截断。而使用"-o"则没有这样的问题,因为sort在打开文件前先完成数据的读取。但"-o"和"-m"一起使用时,同样不安全。

[root@linuxidc tmp]# sort -t $'\t' -k3n -o system1.txt system.txt

(9).使用"-c"或"-C"检测文件是否排过序。如果已排序,则不返回任何信息,退出状态码为0。如果未排序,退出状态码为1,但"-c"会给出诊断信息,并指明从哪一行开始乱序,而"-C"不返回任何信息。

[root@linuxidc tmp]# sort -c -k3n system.txt ;echo $? sort: system.txt:3: disorder: 3 bsd 1000 600 1

说明system.txt中的第3行开始出现乱序,且退出状态码为1。

[root@linuxidc tmp]# sort -C -k3n system.txt ;echo $? 1 1.3 深入研究sort

咋一看上去,sort的使用方法很简单,不就是"sort -t DELIMITER -k POS1,POS2 file"吗,确实如此,它的man文档也才100来行,连info文档加上一堆废话也才500多行。但事实上,sort命令很难,也可以说很简单,简单是因为不管是复杂功能还是简单功能,用来用去就那么几个选项,难是因为没搞懂它的工作机制和细节时,有些时候的结果会比较出人意料,也不知道为什么会如此。

本小节主要讲理论和工作机制的细节,偶尔给出几个示例,所以遇到疑惑时请自行测试,当然也欢迎在博客下方留言。另外,"--debug"(CentOS7才支持该选项)选项对排疑解惑有极大帮助,所以应该善用该选项。

(1).sort命令默认按照字符集的排序规则进行排序,可以指定"-d"选项按照字典顺序排序,指定"-n"按照数值排序,指定"-M"按照字符格式的月份规则排序,指定"-h"按照文件容量大小规则排序。

字符集排序规则和字典排序规则对能识别的字符来说,顺序一般是一致的,几种常见字符的顺序为:"空字符串



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3