awk сгруппировать по нескольким столбцам и вывести максимальное значение с не-первичным ключом

awk gawk

2584 просмотра

3 ответа

Я новичок в этом сайте и пытаюсь выучить awk. Я пытаюсь найти максимальное значение field3, группируясь по field1 и распечатать все поля с максимальным значением. Поле 2 содержит время, что означает, что для каждого элемента 1 есть 96 значений поля 2, поля 3 и поля 4

входной файл: (через запятую)

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 с максимальным значением, как показано в желаемом выводе. пожалуйста помоги.

Автор: foxx Источник Размещён: 12.11.2019 09:14

Ответы (3)


4 плюса

Решение

Проблема здесь в том, что вы не сохраняете всю строку, поэтому при просмотре окончательных данных полные данные для печати отсутствуют.

Что вам нужно сделать, это использовать другой массив, скажем 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
Автор: fedorqui Размещён: 30.05.2016 11:20

3 плюса

С небольшой помощью sortкоманды:

sort -t, -k1,1 -k3,3nr file | awk -F, '!seen[$1]++'
Автор: hek2mgl Размещён: 30.05.2016 11:36

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

Выполняя вычисления min / max, вы всегда должны начинать свое значение min / max с первого считанного значения, а не предполагать, что оно всегда будет меньше или больше некоторого произвольного значения (например, ноль или ноль, если вы пропустите !($1 in max)блок выше) ,

Вам нужен keysмассив, чтобы сохранить порядок ввода при печати вывода. Если вы используете inвместо этого, то порядок вывода будет случайным.

Обратите внимание, что идиоматический синтаксис awk просто:

<condition> { <action> }

не в стиле C:

{ if ( <condition> ) { <action> } }
Автор: Ed Morton Размещён: 30.05.2016 12:22
Вопросы из категории :
32x32