Linux技巧(二):Linux sort命令深入解析 | sort -k M.m,N.n 命令详解

前言

目的:逐步带你了解sort排序,解开-k参数的困惑。

困惑之处:sort -k 1.2,1.2

1.2是什么意思?1.2,1.2又是什么鬼?为什么sort -k 1.2和sort -k 1.2,1.2的排序结果不一致?

本文带你逐步解析。

一、sort语法、参数、及其注意事项

1、语法

语法:

sort [-bcdfimMnr][-o<输出文件>][-t<分隔字符>][+<起始栏位>-<结束栏位>][--help][--verison][文件]

2、参数 

 参数:

-b 忽略每行前面开始出的空格字符。从第一个可见字符开始比较。

-d 排序时,处理英文字母、数字及空格字符外,忽略其他的字符。

-f 排序时,忽略字符大小写.

-i 排序时,除了040至176之间的ASCII字符外,忽略其他的字符。

-c 检查文件是否已经按照顺序排序。

-m 将几个排序好的文件进行合并。

-M 前面3个字母依照月份的缩写进行排序。

-n 依照数值的大小排序。

-o <输出文件> 将排序后的结果存入指定的文件。

-r 降序排列(默认是升序)。

-t <分隔字符> 指定排序时所用的栏位分隔字符。

-k field1[,field2] 按指定的列进行排序。

-u 排序后相同的行只显示一次(默认按整行进行比较)

--help 显示帮助。

--version 显示版本信息。

3、注意事项 

1、排序时,默认是按每行/每个域的首字符排序,数字的优先级要大于字符的优先级

2、不指定升序还是降序时,默认是升序

4、重点难点

重点掌握:-t -n -o  -u  - k,尤其是-k。

其他的参数相对比较容易掌握。 

二、案例数据准备

#vim salary.txt 编辑测试文件数据(工资表,里面的数据是虚拟的)

google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
sohu 30 1500

#vim tt.txt

dell 100 10020 ee
lenovo 200 12202 a
huawei 500 13004 ff
cisco 300 24005 bb

#cp tt.txt t.txt
#vim t.txt

随意在里面添加一些空格,便于暴露出了-t的不足之处。 

dell 100   10020 ee
lenovo 200     12202   a
huawei 500     13004   ff
cisco 300     24005            bb

三、通过案例,由浅入深了解sort

1、-r 指定排序

#sort salary.txt      默认根据首行的首字母,升序排列
#sort -r salary.txt   按首行的首字母,降序排列

 

注:此时,暂不涉及复杂的排序,你想要的排序在-t、-k 这些高级参数里面(先了解-r参数为主)。  

2、-t 指定分隔符,并用-k 指定按哪个域进行排序

1.-t 用空格做分隔符的注意事项

-t 如果需要用空格作为分隔符,-t ' ' 和 -t " " 效果是一样的(引号中间,只能有1个空格!

sort -t ' ' -k 4 tt.txt  以空格为分隔符,按第4个域进行排列(答案:符合预期)
sort -t ' ' -k 4 t.txt   以空格为分隔符,按第4个域进行排列(答案:不符预期)

 注:在准备工作中,tt.txt中的数据是规则的,彼此之间只有1个空格; t.txt中的数据是不规则的,彼此之间空格随机。

到此得出结论:-t ‘ ’直接处理不规则的文本格式,是难以胜任的,如果一定要这么做,需要对文件预处理一遍,达到-t的使用场景。

当然,如果-t 用其他特殊字符时(如冒号:),比空格会要好用一些。

2.-t 常用组合 -k 和 -n (同时指定多个域进行排序

题目:在salary中,按薪水进行降序排列,薪资相同时,按公司人数升序排列。 

sort -t' '  -n -k 3r -k 2 salary.txt 

 注:-n是全局参数,所有指定的域都有效(按数值排序);3r中的紧跟这数字的r是局部参数仅对-k 3r中r前面的数字所对应的3个域有效。后面的 -k 2 没有指定降序,那么默认第2个域就是升序排列的。

3、-o把结果输出到指定文件

在sort排序中,如果用 > 重定向来把结果输出到源文件,源文件会被置为空。

此时,-o的作用就凸显出来了。

#cp salary.txt s.txt 复制一份测试数据
#sort -t' ' -k 3r s.txt -o s.txt  排序后,内容用-o输出回原文件
#cat s.txt 发现内容重新按工资高低排序了

#sort -t' ' -k 3 s.txt > s.txt  排序后,内容重定向回原文件
#cat s.txt 发现内容被清空了

 

 实验结果表明:如果要把排序的结果回写到源文件,需要用-o参数,不能用重定向。

4、-n按数值大小排序(重点)

sort在实际排序过程中:
如果不用参数-n,则会把数字当做字符来排序
出现10 <2 的情况,要想把10 和 2 当做完整的数字来排序,需要添加-n这个选项

#vim num.txt
#cat num.txt 
#sort -t' '  -k 2 num.txt  按第二个域排序
#sort -t' '  -k 2n num.txt 按第二个域数值的大小排序
#sort -t' '  -k -n 2 num.txt 按第二个域数值的大小排序

tom 10
su 15
john 2
han 20
bell 25
jom 7

5、-u 去除重复行 | -k M,N消除指定域的重复行

#sort -u salary.txt 去除重复行(-u不配合其他任何参数时:仅对整行所有域都相同,且第二次以后出现的重复行消除)
#sort -t' ' -u -k 1 salary.txt    希望能按第一个域,如果有重复的给以消除(未能达到效果)
#sort -t' ' -u -k 1,1 salary.txt  按第一个域,消除后面的重复行(达到预期)

 解析:

sort排序的时候,-u不配合其他任何参数时,只有完全相同的重复行才会被消除。

这里隐含了一个知识点,那就是start 第一个域的第一个字符~end 最后一个域的最后一个字符,如果完全相同,仅保留第一次出现的行,后面出现的相同行都会被消除。

-K M,N (为了便于理解这里的M,N仅代表两个不同的整数)

M的意思是,从哪个域开始作为比较的依据;N截止到哪个域比较结束。M,N是一个(域的)范围,如果这个M,N结合-u使用。那么-u的比较范围就是M域和N域之间的这段内容。

如果数字N被省略,那么-u比较的范围就是从M域开始,一直到每行的最后一个域的最后一个字符。

6、-k 的高级用法-k1.2,3.5 (重难点

通过上一案例5的学习,对-k M,N有了一定了解,接下来的内容相对会比较容易理解一些。

首先理解,逗点.后面紧跟的数字,在其中的这个含义。

这个数字的意思是:从逗点.前面数字所在域的第几个字符,开始。

1.理论 

理论知识点:

如果抛开M,N之间的逗号,单独说这个逗点

-k 1.2 意思就是,从第1个域的第二个字符开始;同理 -k 2.3 就是从第2个域的第三个字符开始。

2.案例深入解析

案例:仅仅按工资表中第一个域的第二个字符升序排列

#sort -t ' ' -k 1.2 salary.txt
#sort -t ' ' -k 1.2,1.2  salary.txt

解析:上面的命令,哪个得出的结果,更符合题目要求?

显然是第二个命令更符合题目要求,因为第一个命令省略了-k M,N中的第二个参数。直接导致,该命令会从第一个域的第2个字符开始计算排序,一直计算到最后一个域的最后一个字符。此时,在第二个字符都是o的情况下,自然会去比较第三个字符,第三个字符是h、o,自然h会排在前面。

案例总结:
-k1.2,1.2  仅仅且只按照第一个域的第二个字母进行排序,不会再按其他字符进行排序。

-k1.2 先按照第一个域的第二个字母进行排序,第二个字母如果一样,再按照第二个字母后面的字母进行排序,依次类推,直到行尾最后一个字符。
也就是说:google 和 sohu的第二个字母都是o,就开始看第三个字母,显然第三个字母h应该排在o的前面。

想必,到这里 -k1.2,3.5,你一定可以清晰的说出它的含义吧。平时,如果用到仅以某个域进行排序时,一定要用 -k M,N(此时M=N)

3.总结

-k M.m,N.n
-k的语法总体是以逗号为分隔的,前面是M是start部分,后面的N是end部分。
其中M.m,逗点.意思是从第M个域的第m个字符开始进行排序;N.n,逗点.意思是截止到第N个域的第n个字符截止,不再用n后面的字符排序。


平时我们默认不带N.n的,省略了,有时候这样是不够严谨的,如果省略,默认N.n,会排序到最后一个域的最后一个字符。
如果遇到这样的需求,仅仅用某个域进行排序,就需要用到M,N了(此时M=N)。

M.m和N.n,真实语法格式是M.m[参数],N.n[参数],Modifier参数包含[b、d、f、i、n 或 r] 。

官方语法:
官方语法格式:-k [ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]

注:看完以上案例,官方的语法一目了然了,如果上来就给出官方语法,看着就懵逼不是。

四、后记 

        在准备这篇文章时,翻阅了大量的资料,尽己所能,以最简洁的方式,把该知识点分享给大家。因案例的局限性,难免可能出现纰漏,如果有不当之处,望给以指正。谢谢,大家共同学习、进步。

如果你觉得还不错,赶快点赞收藏吧!

  • 53
    点赞
  • 113
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值