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