2009-10-29 2 views
1

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

myprogram | awk '/chk/ { if ($12 > $13) printf("%s %d\n", $1, $12 - $13); else printf("%s %d\n", $1, $13 - $12) } ' | awk '!x[$0]++' 

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

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 

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

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 

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

+0

Если вы оказались в сжатом пространстве и скорости, и это не преждевременная оптимизация, вы можете заменить ваш 'if ... printf ... else ... printf ...' короче и на ($ 12> $ 13) * 2 - 1) * ($ 12 - $ 13)) ' –

+0

Также, как и в моей системе, быстрее« abs »()' бедных ': printf («% s% d \ n», $ 1, , обратите внимание, что ваша команда 'awk', которая фильтрует строки в'/chk/', может быть объединена в мой сценарий ниже (с модами для сохранения соответствующих полей« prev »вместо целой строки и т. д.), поэтому вы вызываете 'awk' один раз. В верхней части моего скрипта 's' будет установлено значение' (($ 12> $ 13) * 2 - 1) * ($ 12 - $ 13) '* (untested) * –

ответ

2

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

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

Гораздо быстрее, и поскольку память является проблемой (это встроенная среда), я перехожу к этому как к правильному ответу. – Jamie

1

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

... | awk '{ if ($2 > x[$1]) x[$1] = $2 } END { for (k in x) printf "%s %s", k, x[k] }' 
+0

Красиво сделано. Огромное спасибо. – Jamie

+0

Просто отсутствует «\ n» в printf(). В противном случае отлично. – Jamie

+0

Ах, правильно. Я имел это в своей тестовой версии, но забыл, когда печатал ее здесь. :) – jamessan

Смежные вопросы