awk按多列分组,并使用非主键打印最大值

时间:2016-05-30 10:46:37

标签: awk gawk

我是这个网站的新手,并试图学习awk。我试图找到field3的最大值,按field1分组并打印所有具有最大值的字段。字段2包含时间,这意味着每个item1有96个field2,field3和field4

的值

输入文件:(以逗号分隔)

item1,00:15,10,30
item2,00:45,20,45
item2,12:15,30,45
item1,00:30,20,56
item3,23:00,40,44
item1,12:45,50,55
item3,11:15,30,45

期望的输出:

item1,12:45,50,55
item2,12:15,30,45
item3,11:15,30,45

到目前为止我尝试了什么:

BEGIN{
FS=OFS=","}
{
if (a[$1]<$3){
   a[$1]=$3}
}
END{
for (i in a ){
print i,a[i]
}

但这仅打印

item1,50
item2,30
item3,30

但我需要打印相应的field2和field4,其最大值如所需的输出所示。请帮忙。

3 个答案:

答案 0 :(得分:3)

这里的问题是你没有存储整行,所以当你查看最终数据时,没有完整的数据要打印。

您需要做的是使用另一个数组,比如data[index]=full line

BEGIN{
FS=OFS=","}
{
 if (a[$1]<$3){
   a[$1]=$3
   data[$1]=$0}       # store it here!
}
END {
   for (i in a )
       print data[i]  # print it here
}

或者作为一个单行:

$ awk 'BEGIN{FS=OFS=","} {if (a[$1]<$3) {a[$1]=$3; data[$1]=$0}} END{for (i in a) print data[i]}' file
item1,12:45,50,55
item2,12:15,30,45
item3,23:00,40,44

答案 1 :(得分:3)

sort命令的帮助下:

sort -t, -k1,1 -k3,3nr file | awk -F, '!seen[$1]++'

答案 2 :(得分:1)

要完成这项工作,你需要:

$ cat tst.awk
BEGIN { FS="," }
!($1 in max) {
    max[$1]  = $3
    data[$1] = $0
    keys[++numKeys] = $1
}
$3 > max[$1] {
    max[$1]  = $3
    data[$1] = $0
}
END {
    for (keyNr=1; keyNr<=numKeys; keyNr++) {
        print data[keys[keyNr]]
    }
}

$ awk -f tst.awk file
item1,12:45,50,55
item2,12:15,30,45
item3,23:00,40,44

在进行最小/最大计算时,您应始终使用读取的第一个值来设定最小值/最大值,而不是假设它始终小于或大于某个任意值(例如,如果您为零或零跳过上面的!($1 in max)块。

打印输出时,您需要keys数组来保留输入顺序。如果您使用in代替,那么输出顺序将是随机的。

请注意,惯用的awk语法很简单:

<condition> { <action> }

不是C风格:

{ if ( <condition> ) { <action> } }