Вопрос

Я передаю вывод программы через некоторые команды awk, и я почти там, где мне нужно. Команда до сих пор:

myprogram | awk '/chk/ { if ( $12 > $13) printf("%s %d\n", $1, $12 - $13); else  printf("%s %d\n", $1, $13 - $12)  }  ' | awk '!x[
GR_CB20-chk_2, 0
GR_CB20-chk_2, 3
GR_CB200-chk_2, 0
GR_CB200-chk_2, 1
GR_HB20-chk_2, 0
GR_HB20-chk_2, 6
GR_HB20-chk_2, 0
GR_HB200-chk_2, 0
GR_MID20-chk_2, 0
GR_MID20-chk_2, 3
GR_MID200-chk_2, 0
GR_MID200-chk_2, 2
]++'

Последний бит - это uniq бедняка, которого нет у моей цели. При условии, что приведенная выше команда выдает такой вывод:

GR_CB20-chk_2, 3
GR_CB200-chk_2, 1
GR_HB20-chk_2, 6
GR_HB200-chk_2, 0
GR_MID20-chk_2, 3
GR_MID200-chk_2, 2

То, что я хотел бы иметь, это:

<*>

То есть я хотел бы напечатать только строку, которая имеет максимальное значение для данного тега (первое «поле»). Приведенный выше пример представляет данные at в том смысле, что выходные данные будут отсортированы (как если бы они были переданы через команду sort ).

Это было полезно?

Решение

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

#!/usr/bin/awk -f
{
    s = substr(<*>, 0, match(<*>, /,[^,]*$/))
    if (s != prevs) {
        if ( FNR > 1 ) print prevline
        prevval = $2
        prevline = <*>
    }
    else if ( $2 > prevval ) {
        prevval = $2
        prevline = <*>
    }
    prevs = s
}
END {
    print prevline
}

Другие советы

Если вам не нужно, чтобы элементы были в том же порядке, в котором они были выведены из myprogram, сработает следующее:

... | awk '{ if ($2 > x[$1]) x[$1] = $2 } END { for (k in x) printf "%s %s", k, x[k] }'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top