"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"按照文件容量大小规则排序。
字符集排序规则和字典排序规则对能识别的字符来说,顺序一般是一致的,几种常见字符的顺序为:"空字符串<空白字符<数值<a<A<b<B<...<z<Z"。
指定不同的排序规则,不仅改变排序时的依据,还间接影响排序时的行为,因为不同排序规则能够识别的字符类型不同。至于如何影响,见下面的(4)。
(2).sort使用"-t"选项指定的分隔符对每行进行分割,得到多个字段,分隔符不作为字段的内容。默认的分隔符为空白字符和非空白字符之间的空字符,并非网上众多文章所说的空格或制表符(原文:By default, fields are separated by the empty string between a non-blank character and a blank character.)。
例如," foo bar"默认将分隔为两个字段" foo"和" bar",而使用空格作为分隔符时将分隔为三个字段:第一个字段为空,第二个字段和第三个字段为"foo"和"bar"。使用下面三个sort语句可以验证默认的分隔符并非空格。
[root@linuxidc ~]# echo -e " 234 bar\n 123 car" | sort -t ' ' -b -k3 234 bar 123 car [root@linuxidc ~]# echo -e " 234 bar\n 123 car" | sort -b -k2 234 bar 123 car [root@linuxidc ~]# echo -e " 234 bar\n 123 car" | sort -b -k3 # -k3指定的字段超出了范围,所以key为空 123 car 234 bar
(3).使用"-k"选项指定排序的key。不指定排序key时,整行将成为排序key,即对整行进行排序。
key由字段组成,格式为"POS1,[POS2]",表示每行排序的起始和终止位置。也就是说,key才是排序的对象。
POS的格式为"F[.C][OPTS]",其中F表示字段的序号,C表示该字段中字符的序号。字段和字符的位置都从1开始计算。如果POS2的字符位置指定为0,则表示POS2字段中的最后一个字符。如果POS1中省略".C",则默认值为1(字段的起始字符),如果POS2中省略".C",默认值为0(字段的终止字符)。使用"-b"选项忽略前导空白字符时,C从第一个非空白字符开始计算。如果F或C超出了有效范围,则该key为空,例如一行只有3个字段,却指定了"-k4",或者第2字段只有3个字符,却指定了"-k2.5"。