【问题标题】:select lines with duplicate columns by a specific value按特定值选择具有重复列的行
【发布时间】:2013-06-22 15:29:21
【问题描述】:

我有这样的输入:

LineA parameter1 parameter2 56  
LineB parameter1 parameter2 87
LineB parameter1 parameter2 56
LineB parameter1 parameter2 90
LineC parameter1 parameter2 40  

我想打印每一行,但如果第一列 ($1) 重复,则只打印最后一列 ($4) 中具有最高值的行。

所以输出应该是这样的:

LineA parameter1 parameter2 56
LineB parameter1 parameter2 90
LineC ...

【问题讨论】:

    标签: regex perl sed awk pattern-matching


    【解决方案1】:

    尝试以下操作(假设字段 4 始终 >= 0)

    数组b 用于跟踪字段4 中字段1 中唯一值的最大值。数组a(由字段1 键入)包含相应的记录。随着每条记录的处理,记录被添加到数组a,并且字段4被添加到数组b,如果 1. 字段 1 中第一次遇到值或 2. 字段 4 中的值超过了b 中字段 1 中的值的现有值。 最后打印出数组a

     awk '$4 > b[$1] {a[$1] = $0; b[$1] = $4}
     END{for (x in a) {print a[x]}}'
    

    【讨论】:

    • +1,但您只需要检查$4 > b[$1]} -- 如果尚未看到$1,则b[$1] 将被视为零。更具描述性的变量名称可能会有所帮助。
    • @user2245731,请注意输出的顺序不保证与输入的顺序相同:awk 关联数组不保留插入顺序。
    • 谢谢,但您能否添加一些代码解释。谢谢:)
    • @user2245731,添加了一些解释。希望它澄清,描述不是我的强项
    • 我的意思是整个条件只需要$4>b[$1]——你根本不需要!($1 in a)。如果 $1 不在 a 中,则 b[$1] == 0 因此 $4 将大于 b[1]。假设第 4 列中的值都是正数。
    【解决方案2】:

    GNU 代码

    awk 'BEGIN {SUBSEP=OFS} $4>a[$1,$2,$3] {a[$1,$2,$3]=$4} END {for (i in a) {print i,a[i]}}' file
    

    【讨论】:

    • 不可读。试试awk 'BEGIN {SUBSEP=OFS} $4>a[$1,$2,$3] {a[$1,$2,$3]=$4} END {same as what you have}'
    【解决方案3】:

    awk中的另一种方式:

    awk '
    fld1!=$1 && NR>1 {print line}
    fld1==$1 {line=(fld4>$4)?line:$0;next}
    {line=$0;fld1=$1;fld4=$4;next}
    END{print line}' file
    

    【讨论】:

      猜你喜欢
      • 2019-07-06
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 2021-02-06
      • 1970-01-01
      相关资源
      最近更新 更多