日期:2014-05-16 浏览次数:20864 次
Linux sort命令的原理是逐行按字符进行比较排序,当然,也可以通过命令行参数设定按数字进行比较,或者指定行间的分隔符,对某一个或一些字段按照自己指定的规则进行排序。这是一个很常用而且很方便的命令,但是其中的一些细节需要注意,否则会得到错误的排序结果。
1. 比较方式
前面说过,sort命令默认是按照字符串排序,真的是这样么?看看sort的help信息,末尾有这样的文字:
*** WARNING *** The locale specified by the environment affects sort order. Set LC_ALL=C to get the traditional sort order that uses native byte values.
看来,环境变量也能影响sort的排序结果。实际试试看:
~$ cat text 11$ 1{1 ~$ sort text 1{1 11$ ~$ echo $LC_ALL ~$
论ASCII字符的大小,’{’应该比’1’大,但是上面的结果显示,当LC_ALL变量为空值时,sort命令输出了错误的排序结果。不过,在更多的平台上实验发现,LC_ALL为空的时候并不一定会输出这个错误的结果,具体原因不详。不过,如果按照sort的帮助信息设置LC_ALL,则结果是正确的,’1’排在’{’前面。
如果了解LC***系列的变量,其实只需要设置LC_COLLATE即可,该变量控制的是字符串的排序方式,在手头上的几种平台上实验,结果都是正确的。
2. 按数字排序
加-n参数按数字排序。如果一行中还有非数字字符,则按照非数字字符前面的数字大小进行排序。
~$ cat text 11$ 1{1 ~$ export LC_ALL=C ~$ sort text 11$ 1{1 ~$ sort -n text 1{1 11$
3. 重定向
一般sort命令将排序结果输出到终端,如果想写入文件可以用重定向的方式,但是,如果想让排序结果直接写到排序前的文件,用一般的重定向方式sort file_name > file_name达不到效果,需要用sort命令的-o参数。
4. 分隔字段
默认的排序是以行为单位的排序,如果想按照某个字段进行排序,可以用-t选项指定字段分隔符,-k指定要排序的字段。
-k参数的格式为-k start[,end],需要注意的是,如果省略了end,则需要比较到行末,例如:
~$ cat text 1|101|2 1|10|2 ~$ echo $LC_ALL C ~$ sort -t "|" -k 2 text 1|101|2 1|10|2 ~$ sort -t "|" -k 2,2 text 1|10|2 1|101|2
虽然10排在101前面,但是不指定字段结束时,默认会继续比较,即比较’|’和’1’,所以有上面的结果。
通常,我们只希望按照一个或者多个字段排序,而不希望从某个字段开始一直比较到行