一、常用用法
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
“-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”,内容如下:
a d c
执行sort a.txt命令,得到如图1所示结果:
图1
备注:
执行sort -d a.txt命令,得到相同结果。
3.2、实验2
有文件“a.txt”,内容如下:
1.2E10 2.4 01.245
执行sort -g a.txt命令,得到如图2所示结果:
图2
3.3、实验3
有文件“a.txt”,内容如下:
JAN SEP DEC OCT
执行LC_ALL=C sort -M a.txt命令,得到如图3所示结果:
图3
注意:
执行命令时加上“LC_ALL=C”是因为在有些语系环境中,“JAN,SEP,DEC,OCT”并不表示月份,故而JAN
也不成立。比如执行LC_ALL=zh_CN.utf8 sort -M a.txt命令,得到如图4所示结果。
图4
此时再执行LC_ALL=zh_CN.utf8 sort -M a.txt命令,就能得到如图5所示结果,这符合预期。
图5
3.4、实验4
有文件“a.txt”,内容如下:
1G 1K 1M
执行sort -h a.txt命令,得到如图6所示结果:
图6
3.5、实验5
有文件“a.txt”,内容如下:
100 0000001 000000001000
执行sort -n a.txt命令,得到如图7所示结果:
图7
3.6、实验6
有文件“a.txt”,内容如下:
a b c
执行sort -r a.txt命令,得到如图8所示结果:
图8
3.7、实验7
有文件“a.txt”,内容如下:
a b B A
执行sort a.txt命令,得到如图9所示结果:
图9
发现此时有“LC_ALL=zh_CN.utf8”,由此可知在“zh_CN.utf8”语系环境中,字典序中的大小写字母紧邻而列。
再执行LC_ALL=C sort a.txt命令,得到如图10所示结果,可知在“C”语系环境中,字典序中的大小写字母非紧邻而列,需要加上“-f”选项,才能达到“使大小写字母紧邻而列”的要求,即执行LC_ALL=C sort -f a.txt命令,执行命令后可得到如图11所示结果,这符合预期。
图10
图11
3.8、实验8
有文件“a.txt”,内容如下:
2 1 1 1 1 2 3 6 3 2 4 5
执行sort a.txt命令(以整行记录内容作为比较关键词),得到如图12所示结果:
图12
执行sort -k 2n a.txt命令(从第2个字段前导分隔符开始到行尾为止内容作为比较关键词),得到如图13所示结果:
图13
执行sort -k 2,2n -k 4,4n a.txt命令(第一个比较关键词是“从第2个字段前导分隔符开始到第2个字段末尾字符为止内容”,第二个比较关键词是“从第4个字段前导分隔符开始到第4个字段末尾字符为止内容”),得到如图14所示结果:
图14
3.9、实验9
有文件“c.txt”,内容如下:
1 R2 a 4 R3 b 3 R10 c
执行sort -k 2.2n c.txt命令(从第2个字段第2个字符开始到行尾为止内容作为比较关键词,“第2个字段第2个字符”实际是3行中的“R”字符,前导分隔符作为字段一部分),得到如图15所示结果:
图15
执行sort -k 2.3n c.txt命令(从第2个字段第3个字符开始到行尾为止内容作为比较关键词,3行中的“第2个字段第3个字符”分别是“2”,“3”和“1”,前导分隔符作为字段一部分),得到如图16所示结果:
图16
执行sort -k 2.2b,2n c.txt命令(从第2个字段第2个字符开始到第2个字段末尾字符为止内容作为比较关键词,由于加上“b”选项,不将字段前导分隔符作为字段一部分,故而3行中的“第2个字段第2个字符”分别是“2”,“3”和“1”),得到如图17所示结果:
图17
3.10、实验10
有文件“a.txt”,内容如下:
1 bat 51 2 animal 62 3 check 75 4 car 84
执行LC_ALL=C sort -k 2.1b,2.1b -k 3.2b,3.2bn a.txt命令(第一个比较关键词是“第2个字段的第1个字符”,第二个比较关键词是“第3个字段的第2个字符”,前导分隔符不作为字段一部分),得到如图18所示结果:
图18
3.11、实验11
有文件“a.txt”,内容如下:
ab1 2ef cd0 5hi ef3 4jk aa3 1cc bb0 4dd
执行LC_ALL=C sort -k 1.3b,2.1bn a.txt命令(从第1个字段第3个字符开始到第2个字段第1个字符为止内容作为比较关键词,即“比较关键词”横跨两个字段,前导分隔符不作为字段一部分),得到如图19所示结果:
图19
3.12、实验12
有文件“e.txt”,内容如下:
126 Mar 8 07:45:09 nod1 /sbin/ccccilio[12712]: INFO: sadasdasdas 2 Mar 9 08:16:22 nod1 /sbin/zzzzo[12712]: sadsdasdas 3 JUN 3 10:16:22 nod1 /sbin/hah 1 Mar 8 17:20:01 nod1 /usr/sbin/cron[1826]: asdasdas 4 Mar 9 06:24:01 nod1 /USR/SBIN/CRON[27199]: aaaasdsd 1 Mar 9 06:24:01 nod1 /USR/SBIN/CRON[27201]: aaadas
执行LC_ALL=C sort -k 2b,2bM -k 3b,3bn -k 4b,4b e.txt命令(第一个比较关键词是“第2个字段,不包括前导分隔符”,第二个比较关键词是“第3个字段,不包括前导分隔符”,第三个比较关键词是“第4个字段,不包括前导分隔符”),得到如图20所示结果:
图20
以上命令的效果是根据时间排序。
3.13、实验13
有文件“e.txt”,内容如下:
Feb 27 2011 23:05 SOMETHING 2011.02.24.avi Feb 11 2011 20:06 SOMETHING 2011.02.10.avi Jan 23 2011 10:42 SOMETHING 2007.12.20.avi Jan 29 2011 09:17 SOMETHING 2011.01.27.avi Feb 12 2010 SOMETHING 2010.02.11.avi Jun 26 2009 SOMETHING 2009.06.25.avi
执行LC_ALL=C sort -k 3b,3bnr -k 1b,1bMr -k 2b,2bnr -k 4b,4br e.txt命令(第一个比较关键词是“第3个字段,不包括前导分隔符”,第二个比较关键词是“第1个字段,不包括前导分隔符”,第三个比较关键词是“第2个字段,不包括前导分隔符”,第四个比较关键词是“第4个字段,不包括前导分隔符”),得到如图21所示结果:
图21
以上命令的效果是根据时间逆序排序。
四、其他
程序实现中使用“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