【问题标题】:How to pick top value from tie-break group using Unix sort如何使用 Unix 排序从抢七组中选择最高值
【发布时间】:2018-04-30 21:30:42
【问题描述】:

我有以下文本文件:

$ cat myfile.txt
foo,a,10
bar,c,33
foo,b,50
bar,a,9
foo,a,20
bar,b,20

我想要做的是按第 2 列和第 3 列(数字降序)排序,最后选择每个第 2 列组的顶部,从而得到 ​​p>

foo,a,20
foo,b,50
bar,c,33

我被这个困住了:

$ sort -t"," -k2 -k3r   test.txt
foo,a,10
foo,a,20
bar,a,9
bar,b,20
foo,b,50
bar,c,33

正确的做法是什么?

【问题讨论】:

    标签: linux bash sorting unix awk


    【解决方案1】:

    您的sort 命令已关闭。 -k 实际上需要一系列字段,因此您的 -k2 被解释为“对从第二个字段到行尾的所有内容进行排序”,它完全忽略了 -k3。您必须明确范围的开始和结束位置。您还想按数字对第三个进行排序。

    以下是所有内容:

    $ sort -t, -k2,2 -k3,3nr myfile.txt
    foo,a,20
    foo,a,10
    bar,a,9
    foo,b,50
    bar,b,20
    bar,c,33
    

    现在您要根据第二个字段选择每个组的第一行。尽管sort 具有对流进行重复数据删除的能力,但它还不够聪明,无法处理这样的复杂场景。幸运的是,我们有 awk:

    $ sort -t, -k2,2 -k3,3nr myfile.txt | awk -F, 'x != $2 { print; x = $2 }'
    foo,a,20
    foo,b,50
    bar,c,33
    

    【讨论】:

    • 已删除的答案建议 !unique[$2]++ 作为 awk 脚本,这似乎也有效:sort -t, -k2,2 -k3,3nr myfile.txt | awk -F, '!unique[$2]++'。不确定这是否比您的解决方案更可取,但字符更少;)
    • 任一 awk 脚本都可以!无论您发现哪个更容易记住以供将来使用。 :)
    【解决方案2】:

    呸呸呸

    纯猛击!!

    regex=',(.+),'
    var="xx"
    for line in $(sort -t, -k2,2 -k3,3nr myfile.txt); do
      if [[ $line =~ $regex ]]; then
        bashrematch=${BASH_REMATCH[1]}
        if [[ "$var" != "$bashrematch" ]]; then
          var=$bashrematch
          echo $line
        fi
      fi
    done
    foo,a,20
    foo,b,50
    bar,c,33
    

    只是为了压缩和缩小代码

    r=',(.+),'; v=""; for l in $(sort -t, -k2,2 -k3,3nr myfile.txt); do [[ $l =~ $r ]] && b=${BASH_REMATCH[1]} && [ "$v" != "$b" ] && v=$b && echo $l; done
    foo,a,20
    foo,b,50
    bar,c,33
    

    【讨论】:

    • 感谢编辑格式化 bash,@dimo414,帖子是在一行中制作的,以符合问题的风格,以及其他答案。您还根据您的喜好将一条正确的线更改为另一条也正确的线。无论哪种方式我都很好,这意味着作为一个练习来学习如何使用 bash 来解决问题。 =)
    【解决方案3】:

    这是纯粹的awk 方法,

     awk -F, '{split(a[$2],b,",");if(b[3]<$3)a[$2]=$0}END{for(i in a)print [i]}' myfile.txt
    

    简要说明,

    • split(a[$2],b,","):将每条记录用','分隔,并将每个字段保存到数组b中。
    • if(b[3]&lt;$3)a[$2]=$0:比较 b[3] 和 $3 以确定是否需要更新 a[$2]
    • 在最后打印数组 a 中的所有内容。

    【讨论】:

      猜你喜欢
      • 2021-10-24
      • 2022-01-11
      • 1970-01-01
      • 2015-03-24
      • 2013-05-04
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多