zoukankan      html  css  js  c++  java
  • sort排序,按指定字段进去重,sort -t "^" -k 8 -su,ls给文件名中数字排序sort -k1.5n,Tab符要转义

    sort

    sort 命令对 File 参数指定的文件中的行排序,并将结果写到标准输出。如果 File 参数指定多个文件,那么 sort 命令将这些文件连接起来,并当作一个文件进行排序。

    sort语法

     
    [root@www ~]# sort [-fbMnrtuk] [file or stdin]
    选项与参数:
    -f  :忽略大小写的差异,例如 A 与 a 视为编码相同;
    -b  :忽略最前面的空格符部分;
    -M  :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;
    -n  :使用『纯数字』进行排序(默认是以文字型态来排序的);
    -r  :反向排序;
    -u  :就是 uniq ,相同的数据中,仅出现一行代表;
    -t  :字段之间的分隔符默认是空格,如果让	作为分隔符,需要转义:-t $'	';
    -k  :以那个区间 (field) 来进行排序的意思
     
    
    对/etc/passwd 的账号进行排序
    
    [root@www ~]# cat /etc/passwd | sort
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    apache:x:48:48:Apache:/var/www:/sbin/nologin
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin

    sort 是默认以第一个数据来排序,而且默认是以字符串形式来排序,所以由字母 a 开始升序排序。

    /etc/passwd 内容是以 : 来分隔的,我想以第三栏来排序,该如何

    [root@www ~]# cat /etc/passwd | sort -t ':' -k 3
    root:x:0:0:root:/root:/bin/bash
    uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    bin:x:1:1:bin:/bin:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin

    默认是以字符串来排序的,如果想要使用数字排序:

    cat /etc/passwd | sort -t ':' -k 3n
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/bin/sh
    bin:x:2:2:bin:/bin:/bin/sh

    默认是升序排序,如果要倒序排序,如下

    cat /etc/passwd | sort -t ':' -k 3nr
    nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
    ntp:x:106:113::/home/ntp:/bin/false
    messagebus:x:105:109::/var/run/dbus:/bin/false
    sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin

    如果要对/etc/passwd,先以第六个域的第2个字符到第4个字符进行正向排序,再基于第一个域进行反向排序。

    cat /etc/passwd |  sort -t':' -k 6.2,6.4 -k 1r      
    sync:x:4:65534:sync:/bin:/bin/sync
    proxy:x:13:13:proxy:/bin:/bin/sh
    bin:x:2:2:bin:/bin:/bin/sh
    sys:x:3:3:sys:/dev:/bin/sh


    查看/etc/passwd有多少个shell:对/etc/passwd的第七个域进行排序,然后去重:

    cat /etc/passwd |  sort -t':' -k 7 -u
    root:x:0:0:root:/root:/bin/bash
    syslog:x:101:102::/home/syslog:/bin/false
    daemon:x:1:1:daemon:/usr/sbin:/bin/sh
    sync:x:4:65534:sync:/bin:/bin/sync
    sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin

    按指定字段进去重:

    sort -t "^" -k 8 -su 29w.csv >278422.csv

    分割符为"^",按第8列排序,-su为去重。 

    ls给文件名中数字排序

    事情是这样的
    想用这种语句for file in `ls /TEST/`按文件名次序调用文件。
    可是结果不是
    [root@localhost TEST]# ls
    expe expe14 expe2 expe25 expe30 expe36 expe41 expe47 expe52 expe58
    expe1 expe15 expe20 expe26 expe31 expe37 expe42 expe48 expe53 expe59
    expe10 expe16 expe21 expe27 expe32 expe38 expe43 expe49 expe54 expe6
    expe11 expe17 expe22 expe28 expe33 expe39 expe44 expe5 expe55 expe7
    expe12 expe18 expe23 expe29 expe34 expe4 expe45 expe50 expe56 expe8
    expe13 expe19 expe24 expe3 expe35 expe40 expe46 expe51 expe57 expe9

    ls expe* |sort -k1.5n
    expe1
    expe2
    expe3
    expe4
    expe5
    expe6
    expe7
    expe8
    expe9
    expe10
    expe11
    expe100

    -k1.5表示第一个字段、第5个字符开始:

    KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where
    F is a field number and C a character position in the field; both are
    origin 1, and the stop position defaults to the line's end. If neither
    -t nor -b is in effect, characters in a field are counted from the
    beginning of the preceding whitespace. OPTS is one or more single-let‐
    ter ordering options [bdfgiMhnRrV], which override global ordering
    options for that key. If no key is given, use the entire line as the
    key.

     
     
     

    让tab作为分隔符,这个时候你可以转义tab:

    $sort -t ' ' -k3n a.txt >a.sort

    sort: multi-character tab ` '  (出错)

    这个不能按照tab分隔符进行字段排序,换成如下两种方式就可以了

    $ sort  -t $' ' -k3n a.txt>a.sort2,

    $ sort -t'<ctrl>v<tab>' -k3,3n a.txt>a.sort

    <ctrl>v<tab>代表先同时按下Ctrl和v键,然后松开,按下tab键。

     
     
    汉字sort排序,要设置:LANG=GBK
     
     
     
     
     
     
     sort命令的k选项大讨论

    [正文开始]
    有时候学习脚本,你会发现sort命令后面跟了一堆类似-k1,2,或者-k1.2 -k3.4的东东,有些匪夷所思。今天,我们就来搞定它—-k选项!

    1 准备素材

    1. $ cat facebook.txt
    2. google 110 5000
    3. baidu 100 5000
    4. guge 50 3000
    5. sohu 100 4500

    第一个域是公司名称,第二个域是公司人数,第三个域是员工平均工资。(除了公司名称,其他的别信,都瞎写的^_^)

    2 我想让这个文件按公司的字母顺序排序,也就是按第一个域进行排序:(这个facebook.txt文件有三个域)

    1. $ sort -t ' ' -k 1 facebook.txt
    2. baidu 100 5000
    3. google 110 5000
    4. guge 50 3000
    5. sohu 100 4500

    看到了吧,就直接用-k 1设定就可以了。(其实此处并不严格,稍后你就会知道)

    3 我想让facebook.txt按照公司人数排序

    1. $ sort -n -t ' ' -k 2 facebook.txt
    2. guge 50 3000
    3. baidu 100 5000
    4. sohu 100 4500
    5. google 110 5000

    不用解释,我相信你能懂。

    但是,此处出现了问题,那就是baidu和sohu的公司人数相同,都是100人,这个时候怎么办呢?按照默认规矩,是从第一个域开始进行升序排序,因此baidu排在了sohu前面。

    4  我想让facebook.txt按照公司人数排序,人数相同的按照员工平均工资升序排序:

    1. $ sort -n -t ' ' -k 2 -k 3 facebook.txt
    2. guge 50 3000
    3. sohu 100 4500
    4. baidu 100 5000
    5. google 110 5000

    看,我们加了一个-k2 -k3就解决了问题。对滴,sort支持这种设定,就是说设定域排序的优先级,先以第2个域进行排序,如果相同,再以第3个域进行排序。(如果你愿意,可以一直这么写下去,设定很多个排序优先级)

    5 我想让facebook.txt按照员工工资降序排序,如果员工人数相同的,则按照公司人数升序排序:(这个有点难度喽)

    1. $ sort -n -t ' ' -k 3r -k 2 facebook.txt
    2. baidu 100 5000
    3. google 110 5000
    4. sohu 100 4500
    5. guge 50 3000

    此处有使用了一些小技巧,你仔细看看,在-k 3后面偷偷加上了一个小写字母r。你想想,再结合我们上一篇文章,能得到答案么?揭晓:r和-r选项的作用是一样的,就是表示逆序。因为sort默认是按照升序排序的,所以此处需要加上r表示第三个域(员工平均工资)是按照降序排序。此处你还可以加上n,就表示对这个域进行排序时,要按照数值大小进行排序,举个例子吧:

    1. $ sort -t ' ' -k 3nr -k 2n facebook.txt
    2. baidu 100 5000
    3. google 110 5000
    4. sohu 100 4500
    5. guge 50 3000

    看,我们去掉了最前面的-n选项,而是将它加入到了每一个-k选项中了。

    6 -k选项的具体语法格式

    要继续往下深入的话,就不得不来点理论知识。你需要了解-k选项的语法格式,如下:

    [ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]

    这个语法格式可以被其中的逗号(“,”)分为两大部分,Start部分和End部分。

    先给你灌输一个思想,那就是“如果不设定End部分,那么就认为End被设定为行尾”。这个概念很重要的,但往往你不会重视它。

    Start部分也由三部分组成,其中的Modifier部分就是我们之前说过的类似n和r的选项部分。我们重点说说Start部分的FStart和C.Start。

    C.Start也是可以省略的,省略的话就表示从本域的开头部分开始。之前例子中的-k 2和-k 3就是省略了C.Start的例子喽。

    FStart.CStart,其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。

    同理,在End部分中,你可以设定FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将CEnd设定为0(零),也是表示结尾到“域尾”。

    7 突发奇想,从公司英文名称的第二个字母开始进行排序:

    1. $ sort -t ' ' -k 1.2 facebook.txt
    2. baidu 100 5000
    3. sohu 100 4500
    4. google 110 5000
    5. guge 50 3000

    看,我们使用了-k 1.2,这就表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序。你会发现baidu因为第二个字母是a而名列榜首。sohu和google第二个字符都是o,但sohu的h在google的o前面,所以两者分别排在第二和第三。guge只能屈居第四了。

    8 又突发奇想,,只针对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行降序排序:

     

    1. $ sort -t ' ' -k 1.2,1.2 -k 3,3nr facebook.txt
    2. baidu 100 5000
    3. google 110 5000
    4. sohu 100 4500
    5. guge 50 3000

    由于只对第二个字母进行排序,所以我们使用了-k 1.2,1.2的表示方式,表示我们“只”对第二个字母进行排序。(如果你问“我使用-k 1.2怎么不行?”,当然不行,因为你省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序)。对于员工工资进行排序,我们也使用了-k 3,3,这是最准确的表述,表示我们“只”对本域进行排序,因为如果你省略了后面的3,就变成了我们“对第3个域开始到最后一个域位置的内容进行排序”了。

    9 在modifier部分还可以用到哪些选项?

    可以用到b、d、f、i、n 或 r。

    其中n和r你肯定已经很熟悉了。

    b表示忽略本域的签到空白符号。

    d表示对本域按照字典顺序排序(即,只考虑空白和字母)。

    f表示对本域忽略大小写进行排序。

    i表示忽略“不可打印字符”,只针对可打印字符进行排序。(有些ASCII就是不可打印字符,比如a是报警,是退格, 是换行, 是回车等等)

    10 思考思考关于-k和-u联合使用的例子:

    1. $ cat facebook.txt
    2. google 110 5000
    3. baidu 100 5000
    4. guge 50 3000
    5. sohu 100 4500

    这是最原始的facebook.txt文件。

    1. $ sort -n -k 2 facebook.txt
    2. guge 50 3000
    3. baidu 100 5000
    4. sohu 100 4500
    5. google 110 5000
    6. $ sort -n -k 2 -u facebook.txt
    7. guge 50 3000
    8. baidu 100 5000
    9. google 110 5000

    当设定以公司员工域进行数值排序,然后加-u后,sohu一行就被删除了!原来-u只识别用-k设定的域,发现相同,就将后续相同的行都删除。

    1. $ sort -k 1 -u facebook.txt
    2. baidu 100 5000
    3. google 110 5000
    4. guge 50 3000
    5. sohu 100 4500
    6. $ sort -k 1.1,1.1 -u facebook.txt
    7. baidu 100 5000
    8. google 110 5000
    9. sohu 100 4500

    这个例子也同理,开头字符是g的guge就没有幸免于难。

    1. $ sort -n -k 2 -k 3 -u facebook.txt
    2. guge 50 3000
    3. sohu 100 4500
    4. baidu 100 5000
    5. google 110 5000

    咦!这里设置了两层排序优先级的情况下,使用-u就没有删除任何行。原来-u是会权衡所有-k选项,将都相同的才会删除,只要其中有一级不同都不会轻易删除的:)(不信,你可以自己加一行sina 100 4500试试看)

    11 最诡异的排序:

    1. $ sort -n -k 2.2,3.1 facebook.txt
    2. guge 50 3000
    3. baidu 100 5000
    4. sohu 100 4500
    5. google 110 5000

    以第二个域的第二个字符开始到第三个域的第一个字符结束的部分进行排序。

    第一行,会提取0 3,第二行提取00 5,第三行提取00 4,第四行提取10 5。

    又因为sort认为0小于00小于000小于0000….

    因此0 3肯定是在第一个。10 5肯定是在最后一个。但为什么00 5却在00 4前面呢?(你可以自己做实验思考一下。)

    答案揭晓:原来“跨域的设定是个假象”,sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分,而不会把第三个域的开头字符纳入比较范围。当发现00和00相同时,sort就会自动比较第一个域去了。当然baidu在sohu前面了。用一个范例即可证实:

    1. $ sort -n -k 2.2,3.1 -k 1,1r facebook.txt
    2. guge 50 3000
    3. sohu 100 4500
    4. baidu 100 5000
    5. google 110 5000

    12 有时候在sort命令后会看到+1 -2这些符号,这是什么东东?

    关于这种语法,最新的sort是这么进行解释的:

    On older systems, 'sort' supports an obsolete origin-zero syntax '+POS1 [-POS2]' for specifying sort keys.  POSIX 1003.1-2001 (*note Standards conformance::) does not allow this; use '-k' instead.

    原来,这种古老的表示方式已经被淘汰了,以后可以理直气壮的鄙视使用这种表示方法的脚本喽!

    (为了防止古老脚本的存在,在这再说一下这种表示方法,加号表示Start部分,减号表示End部分。最最重要的一点是,这种方式方法是从0开始计数的,以前所说的第一个域,在此被表示为第0个域。以前的第2个字符,在此表示为第1个字符。明白?)

    结束语:

    本文是互联网上仅有的比较全的关于sort的k选项的论述文章,如需转载请务必注明“转自Linux大棚-Linux主题博客”,谢谢各位:)

    sort的-k选项基本就是这堆内容了,如果大家有什么补充,就留言吧:) 欢迎交流!

     
  • 相关阅读:
    inux修改profile文件出错后所有命令不能用
    windows常用批处理脚本
    Namespace + functions versus static methods on a class 命名空间函数和类的静态方法对比
    vs2008(visual studio)使用cppcheck
    保存文件为UTF8格式(Writing UTF8 files in C++).
    C++ smtp发送邮件类(ssl/tls)转自codeproject。
    CString、TCHAR、WCHAR 字符串等转BSTR的几种方法。
    C/C++中全局变量的那些事儿
    [C++] 哪本书是对程序员最有影响、每个程序员都该阅读的书?读书排行。
    (转)修改VS2008(vc)中工程/解决方案/类的名字
  • 原文地址:https://www.cnblogs.com/timssd/p/4962293.html
Copyright © 2011-2022 走看看