【问题标题】:Awk Remove lines if one column matches another column, and keep line if max value from another column如果一列与另一列匹配,则 Awk 删除行,如果另一列的最大值则保留行
【发布时间】:2021-06-13 03:05:11
【问题描述】:

我有一个大约 8,000 行的文件。我正在尝试删除第 5 列匹配的行(在本例中为 ga2016mldlzd),但仅保留第 6 列中具有最大值的行。例如,如果给出这个:

-25.559,129.8529,6674.560547,2.0,ga2016mldlzd,6
-25.5596,129.8565,6902.750651,2.0,ga2016mldlzd,7
-25.5450,129.830,969.8079427,2.0,ga2016mldlzd,8
-25.5450,129.834,57.04752604,2.0,ga2016mldlzd,9
-25.57067,129.856,7929.60612,2.0,ga2016mldlzd,10

删除除最后一行以外的所有行,最大值为 10,以获得此值。我很困惑如何在 awk 或 sed 中做到这一点?

-25.57067,129.856,7929.60612,2.0,ga2016mldlzd,10

如果尝试这样做:

awk -F, '!a[$5]++'

但我想保留最后一列,例如“10”列,而不是“6”列。谢谢

【问题讨论】:

  • 您应该包含一些行,其中第 5 列不等于“ga2016mldlzd”,因此我们可以针对您的这部分要求测试潜在的解决方案。您的示例中演示的主题行中的“如果一列与另一列匹配”要求在哪里?我没有看到 2 列中的值相同的任何行。

标签: awk


【解决方案1】:

跟踪最大值和与该最大值关联的行并在最后打印:

awk -F, '
    {
        if ($6>max[$5]) {
            max[$5]=$6
            tl[$5]=$0
            }
    }
END{
    for (l in tl) print tl[l]
}' file

打印:

-25.57067,129.856,7929.60612,2.0,ga2016mldlzd,10

文件的顺序会丢失;即,与原始文件相比,这些组可能会重新排序。



如果您正在处理具有许多不同键的文件 $5 并且并非所有键都可以放入内存中,您可以按第五个字段分组,然后按第六个字段的数值分组。然后让awk 每次第五个字段更改时打印最后一行。既然是排序的,那就是最大值:

sort -t , -k 5,5 -k 6n file |  
awk -F, '
    FNR==1{lf=$5;ll=$0} 
    lf!=$5{print ll}
    {ll=$0; lf=$5}
    END{print $0}' 

# same print out

对于大量$5 uniq 值,第二个方法会更慢但内存更少。

【讨论】:

  • 第二个对海量数据有效。
【解决方案2】:

如果您想保持原始的行顺序,请使用awk:

awk -F, 'NR==FNR {if ($6 > max[$5]) max[$5] = $6; next} $5 in max && max[$5] == $6' file file

-25.57067,129.856,7929.60612,2.0,ga2016mldlzd,10

如果您想过滤ga2016mldlzd,同时保持行的原始顺序,请使用此awk

awk -F, '
NR==FNR {
   if ($5 == "ga2016mldlzd" && $6 > max[$5]) {
      max[$5] = $6
      n = FNR
   }
   next
}
FNR == n' file file

-25.57067,129.856,7929.60612,2.0,ga2016mldlzd,10

【讨论】:

    猜你喜欢
    • 2021-04-21
    • 1970-01-01
    • 2016-11-22
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 2011-09-20
    相关资源
    最近更新 更多