linux命令---sort命令
简介
sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。sort命令既可以从特定的文件,也可以从stdin中获取输入进行排序。
sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
语法 sort [-bcdfimMnr][-o<输出文件>][-t<分隔字符>][+<起始栏位>-<结束栏位>][--help][--verison][文件]
AIX里:
sort [ -A ] [ -b ] [ -c ] [ -d ] [ -f ] [ -i ] [ -m ] [ -n ] [ -r ] [ -u ] [ -o OutFile ] [ -t Character ] [ -T Directory ] [ -y [ Kilobytes ] ] [ -z RecordSize ] [ [ + [ FSkip ] [
.CSkip ] [ b ] [ d ] [ f ] [ i ] [ n ] [ r ] ] [ - [ FSkip ] [ .CSkip ] [ b ] [ d ] [ f ] [ i ] [ n ] [ r ] ] ] ... [ -k KeyDefinition ] ... [ File ... ]
-b:忽略每行前面开始出现的空格字符;
-c:检查文件是否已经按照顺序排序,也可以理解为文件是否分类;
-d:排序时,处理英文字母、数字及空格字符外,忽略其他的字符;
-f:排序时,将小写字母视为大写字母;
-i:排序时,除了040至176之间的ASCII字符外,忽略其他的字符;
-m:将几个排序号的文件进行合并;
-M:将前面3个字母依照月份的缩写进行排序;
-n:依照数值的大小排序;
-r:以相反的顺序来排序;
-t<分隔字符>:指定排序时所用的栏位分隔字符;
-u :忽略相同行
-o<输出文件>:将排序后的结果存入制定的文件;
+<起始栏位>-<结束栏位>:以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
使用实例:
缺省情况下,sort认为一个空格或一系列空格为分隔符。要加入其他方式分隔,使用- t选sort执行时,先查看是否为域分隔设置了- t选项,如果设置了,则使用它来将记录分隔成域0、域1等等;如果未设置,用空格代替。缺省时sort将整个行排序,指定域号的情况例外。
sort对域的参照方式
关于s o r t的一个重要事实是它参照第一个域作为域0,域1是第二个域,等等。s o r t也可以使用整行作为分类依据。
例:常用选项示例
$cat a.log aa:10:1.1 ccc:30:3.3 ddd:40:4.4 bbb:20:2.2 eee:50:5.5 eee:50:5.5 $sort a.log aa:10:1.1 bbb:20:2.2 ccc:30:3.3 ddd:40:4.4 eee:50:5.5 eee:50:5.5
忽略相同行使用-u选项或者uniq:
$sort -u a.log aa:10:1.1 bbb:20:2.2 ccc:30:3.3 ddd:40:4.4 eee:50:5.5
$uniq a.log aa:10:1.1 ccc:30:3.3 ddd:40:4.4 bbb:20:2.2 eee:50:5.5
# -n是按照数字大小排序,-r是以相反顺序,-k是指定需要排序的栏位,-t指定栏位分隔符为冒号
$cat b.log AAA:BB:CC aaa:30:1.6 ccc:50:3.3 ddd:20:4.2 bbb:10:2.5 eee:40:5.4 eee:60:5.1
#将BB列按照数字从小到大顺序排列: $sort -nk 2 -t: b.log AAA:BB:CC bbb:10:2.5 ddd:20:4.2 aaa:30:1.6 eee:40:5.4 ccc:50:3.3 eee:60:5.1
#将CC列数字从大到小顺序排列:$sort -nrk 3 -t: b.log eee:40:5.4 eee:60:5.1 ddd:20:4.2 ccc:50:3.3 bbb:10:2.5 aaa:30:1.6 AAA:BB:CC
注意:排序过程中会出现10比2小的情况。出现这种情况是由于排序程序将这些数字按字符来排序了,排序程序会先比较1和2,显然1小,所以就将10放在2前面喽。这也是sort的一贯作风。如果想改变这种现状,就要使用-n选项,来告诉sort,"要以数值来排序"!
例:-c分类
怎样分辨文件是否已分类?行数很多时,使用sort - c通知sort 文件是否按某种顺序分类。
$cat mm.log Boys in Company C:HK:192:2192 Alien:HK:119:1982 The Hill:KL:63:2972 Aliens:HK:532:4892 Star Wars:HK:301:4102 A Few Good Men:KL:445:5851 Toy Story:HK:239:3972
#检查文件是否分类,结果显示未分类
$sort -c mm.log sort: This line is out of order: Alien:HK:119:1982
#先将其分域,再进行分类 $sort -t: mm.log>mm2.log
$cat mm2.log A Few Good Men:KL:445:5851 Alien:HK:119:1982 Aliens:HK:532:4892 Boys in Company C:HK:192:2192 Star Wars:HK:301:4102 The Hill:KL:63:2972 Toy Story:HK:239:3972
#检查文件是否分类,结果显示已分类
$sort -c mm2.log
$cat mm2.log A Few Good Men:KL:445:5851 Alien:HK:119:1982 Aliens:HK:532:4892 Boys in Company C:HK:192:2192 Star Wars:HK:301:4102 The Hill:KL:63:2972 Toy Story:HK:239:3972
直接使用下边的命令,也分类失败。
$sort -t: -c mm.log>mm3.log sort: This line is out of order: Alien:HK:119:1982
例:-K选项
-k选项的具体语法格式:
FStart.CStart Modifie,FEnd.CEnd Modifier
-------Start--------,-------End--------
FStart.CStart 选项 , FEnd.CEnd 选项
这个语法格式可以被其中的逗号,分为两大部分,Start部分和End部分。Start部分也由三部分组成,其中的Modifier部分就是我们之前说过的类似n和r的选项部分。
C.Start也是可以省略的,省略的话就表示从本域的开头部分开始。FStart.CStart,其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。同理,在End部分中,你可以设定FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将CEnd设定为0(零),也是表示结尾到“域尾”。
注意:“跨域的设定是个假象”,比如(sort -n -k 2.2,3.1 c.log)sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分,而不会把第三个域的开头字符纳入比较范围。
测试数据c.log:第一个域是公司名称,第二个域是公司人数,第三个域是员工平均工资
#按第一个域排序
$ sort -t ‘ ‘ -k 1 c.log
#按第二个域排序,若第二个域值相同,默认规则是从第一个域开始进行升序排序
$ sort -t ‘ ‘ -k 2 c.log
#按照公司人数排序 ,人数相同的按照员工平均工资升序排序
$ sort -n -t ‘ ‘ -k 2 -k 3 c.log
sort支持 -k 2 -k 3这种设定,就是说设定域排序的优先级,先以第2个域进行排序,如果相同,再以第3个域进行排序。
#按照员工工资降序排序(r),如果员工人数相同的,则按照公司人数升序排序:
$ sort -n -t ‘ ‘ -k 3r -k 2 c.log
$ sort -t ‘ ‘ -k 3nr -k 2n c.log
$cat c.log
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
wangyi 200 3000
#1,2 中间是逗号,对第一个域、第二个域排序
$sort -t ' ' -k 1,2 c.log
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
wangyi 200 3000
#从公司英文名称的第二个字母开始进行排序
$sort -t ' ' -k 1.2 c.log
baidu 100 5000
wangyi 200 3000
sohu 100 4500
google 110 5000
guge 50 3000
#以-t作为域分隔符,使用了-k 1.2,表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序。
-k 1,2 与-k 1.2 两个表示的意思不同,需要注意一下。
$sort -t ' ' -k 1.2,1.2 c.log
baidu 100 5000
wangyi 200 3000
google 110 5000
sohu 100 4500
guge 50 3000
$sort -nr -t ' ' -k 1.2,1.2 c.log
wangyi 200 3000
sohu 100 4500
guge 50 3000
google 110 5000
baidu 100 5000
$sort -nr -t ' ' -k 1.2,1.2 -k 3,3 c.log
google 110 5000
baidu 100 5000
sohu 100 4500
wangyi 200 3000
guge 50 3000
$sort -t ' ' -k 1.2,1.2 -k 3,3 c.log
wangyi 200 3000
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
由于只对第二个字母进行排序,所以我们使用了-k 1.2,1.2的表示方式,表示我们“只”对第二个字母进行排序。
(如果你问“我使用-k 1.2怎么不行?”,当然不行,因为你省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序)。
对于员工工资进行排序,我们也使用了-k 3,3,这是最准确的表述,表示我们“只”对本域进行排序,因为如果你省略了后面的3,就变成了我们“对第3个域开始到最后一个域位置的内容进行排序” 了。
modifier部分还可以用到哪些选项,可以用到b、d、f、i、n 或 r。
b表示忽略本域的签到空白符号。
d表示对本域按照字典顺序排序(即,只考虑空白和字母)。
f表示对本域忽略大小写进行排序。
i表示忽略“不可打印字符”,只针对可打印字符进行排序。(有些ASCII就是不可打印字符,比如/a是报警,/b是退格,/n是换行,/r是回车等等)
-K与-u的组合
-u :忽略相同行
$ sort -n -k 2 -u c.log
-u只识别用-k设定的域,发现相同,就将后续相同的行都删除。
$ sort -n -k 2 -k 3 -u c.log
两层排序优先级的情况下,-u是会权衡所有-k选项,将都相同的才会删除,只要其中有一级不同都不会轻易删除的使用-u就没有删除任何行。
例:指定栏位排序(比较老的使用方式)
+<起始栏位>-<结束栏位>:以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
这种方式方法是从0开始计数的,以前所说的第一个域,在此被表示为第0个域。以前的第2个字符,在此表示为第1个字符。传递到m,n。m为域号,n为开始分类字符数;例如4,6意即以第5域分类,从第7个字符开始。
以第2个字段作为排序关键字对文件的内容进行排序。
$cat c.log
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
wangyi 200 3000
$sort +1 -2 c.log
baidu 100 5000
sohu 100 4500
google 110 5000
wangyi 200 3000
guge 50 3000
$sort -n +1 -2 c.log
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
wangyi 200 3000
$sort -r -o d.log +1.0 -1.1 c.log
$cat d.log
wangyi 200 3000
sohu 100 4500
guge 50 3000
google 110 5000
baidu 100 5000
sort -r -o d.log +1.0 -1.1 c.log 表示利用第1个域的第一个字符作为排序关键字反序排列
$ sort -t: +1 mm.log 表示只按第2域(分类键1)分类。
$ ls - l | Sort +5 - 7 利用管道将当前工作目录中的文件送给Sort进行排序,排序关键字是第6个至第8个字段
$ sort -t: +3n mm.log 第3域(分类键3)按数值(n)进行排序
$ sort +0 -2 +3 mm.log 表示开始以域0分类,忽略域2,然后再使用域3分类。?????
注意区分与-K的区别

浙公网安备 33010602011771号