Awk 如果一列与另一列匹配,则删除行,如果另一列的最大值则保留行

时间:2021-06-13 03:05:11

标签: awk

我有一个大约 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”的列。谢谢

2 个答案:

答案 0 :(得分:2)

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

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 值,第二个会更慢,但内存会更少。

答案 1 :(得分:1)

如果您想保持行的原始顺序,请使用此 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
相关问题