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



我有一个大约8000行的文件。我试图删除第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"的列。感谢

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

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

第二,对于大量的$5uniq值,将有更慢但更少的内存。

如果您想维护行的原始顺序,请使用此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

最新更新