Как удалить выделенные строки скриптом awk?
-
22-07-2019 - |
Вопрос
Я передаю вывод программы через некоторые команды 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] }'