一、常用用法
1 | sort [-d | -g | -M | -h | -n] [-r] [-f] [-t CHAR] [-k KEYDEF [-k KEYDEF ... -k KEYDEF]] FILE |
二、含义与选项
2.1、含义
对文件中的记录进行排序。
2.2、选项表示的意思
“-d”:按照字典序排序,默认就是按照字典序排序的。
“-g”:按照数字大小排序,支持科学计数表示法。
“-M”:按照月份大小排序,比如JAN<DEC
。
“-h”:支持识别人类可读形式单位然后进行排序,比如2K<1G
。
“-n”:按照数字大小排序,不支持科学计数表示法。
“-r”:表示反方向排序。
“-f”:排序比较时,忽略大小写。
“-t CHAR”:以“CHAR”字符作为字段间分隔符,默认是以“空格符”或者“Tab”作为分隔符。
“-k KEYDEF”:见“2.2.1、‘-k KEYDEF’”。
2.2.1、“-k KEYDEF”
2.2.1.1、选项用途
默认排序时以整行记录作为比较关键词,通过“-k KEYDEF”选项可以自己指定一个或者多个比较关键词。
2.2.1.2、KEYDEF
“KEYDEF”形如“F[.C][b][,F[.C][b]][OPTS]”。
1、第一个“F[.C][b]”
第一个“F[.C][b]”用来指定关键词的起始位置。“F”表示记录中的第“F”个字段(字段从1开始计数);“C”表示该字段中的第“C”个字符(字符从1开始计数),需要注意的是,省略“.C”,等价于“.1”(即表示该字段的第一个字符);“b”选项表示不将字段的前导分隔符作为该字段的一部分,如果不加“b”选项,那么“F.1”指向的其实是第“F”个字段的前导分隔符。
2、第二个“F[.C][b]”
第二个“F[.C][b]”用来指定关键词的结束位置,如果省略,以行结尾作为该关键词的结束位置。“F”表示记录中的第“F”个字段(字段从1开始计数);“C”表示该字段中的第“C”个字符(字符从1开始计数),需要注意的是,省略“.C”,等价于表示该字段的最后一个字符;“b”选项表示不将字段的前导分隔符作为该字段的一部分,如果不加“b”选项,那么“F.1”指向的其实是第“F”个字段的前导分隔符。
3、OPTS
“OTPS”用来指定排序选项,可选值有“dgMhnrf”。注意跟“2.2、选项表示的意思”中的排序选项进行比对。
4、举例
见实验8,9,10,11,12,13。
三、实验
3.1、实验1
有文件“a.txt”,内容如下:
1 | a |
执行sort a.txt
命令,得到如下所示结果:
1 | a |
备注:
执行sort -d a.txt
命令,得到相同结果。
3.2、实验2
有文件“a.txt”,内容如下:
1 | 1.2E10 |
执行sort -g a.txt
命令,得到如下所示结果:
1 | 01.245 |
3.3、实验3
有文件“a.txt”,内容如下:
1 | JAN |
执行LC_ALL=C sort -M a.txt
命令,得到如下所示结果:
1 | JAN |
注意:
执行命令时加上“LC_ALL=C”是因为在有些语系环境中,“JAN,SEP,DEC,OCT”并不表示月份,故而JAN<SEP<OCT<DEC
也不成立。比如执行LC_ALL=zh_CN.utf8 sort -M a.txt
命令,得到如下所示结果:
1 | DEC |
如果将“a.txt”内容改为:
1 | 06月 |
此时再执行LC_ALL=zh_CN.utf8 sort -M a.txt
命令,就能得到如下所示结果,这符合预期。
1 | 01月 |
3.4、实验4
有文件“a.txt”,内容如下:
1 | 1G |
执行sort -h a.txt
命令,得到如下所示结果:
1 | 1K |
3.5、实验5
有文件“a.txt”,内容如下:
1 | 100 |
执行sort -n a.txt
命令,得到如下所示结果:
1 | 0000001 |
3.6、实验6
有文件“a.txt”,内容如下:
1 | a |
执行sort -r a.txt
命令,得到如下所示结果:
1 | c |
3.7、实验7
有文件“a.txt”,内容如下:
1 | a |
执行sort a.txt
命令,得到如下所示结果:
1 | a |
发现此时有“LC_ALL=zh_CN.utf8”,由此可知在“zh_CN.utf8”语系环境中,字典序中的大小写字母紧邻而列。
再执行LC_ALL=C sort a.txt
命令,得到结果如“结果1”所示,由此可知在“C”语系环境中,字典序中的大小写字母非紧邻而列,需要加上“-f”选项,才能达到“使大小写字母紧邻而列”的要求,即执行LC_ALL=C sort -f a.txt
命令,执行命令后得到结果如“结果2”所示,这符合预期。
结果1
1 | A |
结果2
1 | A |
3.8、实验8
有文件“a.txt”,内容如下:
1 | 2 1 1 1 |
执行sort a.txt
命令(以整行记录内容作为比较关键词),得到如下所示结果:
1 | 1 2 3 6 |
执行sort -k 2n a.txt
命令(从第2个字段前导分隔符开始到行尾为止内容作为比较关键词),得到如下所示结果:
1 | 2 1 1 1 |
执行sort -k 2,2n -k 4,4n a.txt
命令(第一个比较关键词是“从第2个字段前导分隔符开始到第2个字段末尾字符为止内容”,第二个比较关键词是“从第4个字段前导分隔符开始到第4个字段末尾字符为止内容”),得到如下所示结果:
1 | 2 1 1 1 |
3.9、实验9
有文件“c.txt”,内容如下:
1 | 1 R2 a |
执行sort -k 2.2n c.txt
命令(从第2个字段第2个字符开始到行尾为止内容作为比较关键词,“第2个字段第2个字符”实际是3行中的“R”字符,前导分隔符作为字段一部分),得到如下所示结果:
1 | 1 R2 a |
执行sort -k 2.3n c.txt
命令(从第2个字段第3个字符开始到行尾为止内容作为比较关键词,3行中的“第2个字段第3个字符”分别是“2”,“3”和“1”,前导分隔符作为字段一部分),得到如下所示结果:
1 | 1 R2 a |
执行sort -k 2.2b,2n c.txt
命令(从第2个字段第2个字符开始到第2个字段末尾字符为止内容作为比较关键词,由于加上“b”选项,不将字段前导分隔符作为字段一部分,故而3行中的“第2个字段第2个字符”分别是“2”,“3”和“1”),得到如下所示结果:
1 | 1 R2 a |
3.10、实验10
有文件“a.txt”,内容如下:
1 | 1 bat 51 |
执行LC_ALL=C sort -k 2.1b,2.1b -k 3.2b,3.2bn a.txt
命令(第一个比较关键词是“第2个字段的第1个字符”,第二个比较关键词是“第3个字段的第2个字符”,前导分隔符不作为字段一部分),得到如下所示结果:
1 | 2 animal 62 |
3.11、实验11
有文件“a.txt”,内容如下:
1 | ab1 2ef |
执行LC_ALL=C sort -k 1.3b,2.1bn a.txt
命令(从第1个字段第3个字符开始到第2个字段第1个字符为止内容作为比较关键词,即“比较关键词”横跨两个字段,前导分隔符不作为字段一部分),得到如下所示结果:
1 | bb0 4dd |
3.12、实验12
有文件“e.txt”,内容如下:
1 | 126 Mar 8 07:45:09 nod1 /sbin/ccccilio[12712]: INFO: sadasdasdas |
执行LC_ALL=C sort -k 2b,2bM -k 3b,3bn -k 4b,4b e.txt
命令(第一个比较关键词是“第2个字段,不包括前导分隔符”,第二个比较关键词是“第3个字段,不包括前导分隔符”,第三个比较关键词是“第4个字段,不包括前导分隔符”),得到如下所示结果:
1 | 126 Mar 8 07:45:09 nod1 /sbin/ccccilio[12712]: INFO: sadasdasdas |
以上命令的效果是根据时间排序。
3.13、实验13
有文件“e.txt”,内容如下:
1 | Feb 27 2011 23:05 SOMETHING 2011.02.24.avi |
执行LC_ALL=C sort -k 3b,3bnr -k 1b,1bMr -k 2b,2bnr -k 4b,4br e.txt
命令(第一个比较关键词是“第3个字段,不包括前导分隔符”,第二个比较关键词是“第1个字段,不包括前导分隔符”,第三个比较关键词是“第2个字段,不包括前导分隔符”,第四个比较关键词是“第4个字段,不包括前导分隔符”),得到如下所示结果:
1 | Feb 27 2011 23:05 SOMETHING 2011.02.24.avi |
以上命令的效果是根据时间逆序排序。
四、其他
程序实现中使用“LC_COLLATE,LC_ALL,LC_CTYPE”等环境变量,因而最终结果受到“LC_COLLATE,LC_ALL,LC_CTYPE”等环境变量的控制。
参考文献: [1]man sort [2]info sort [3]http://stackoverflow.com/questions/1255782/whats-the-difference-between-general-numeric-sort-and-numeric-sort-options [4]http://stackoverflow.com/questions/12162210/sort-by-just-month-name-and-day-bash [5]http://unix.stackexchange.com/questions/8352/sorting-by-date