Pergunta

Estou tubulação de saída de um programa através de alguns comandos do awk, e estou quase onde eu preciso estar. O comando até agora é:

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

O último bit é uniq de um homem pobre, que não está disponível no meu alvo. Dada a oportunidade o comando acima produz uma saída como esta:

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

O que eu gostaria de ter é o seguinte:

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

Isto é, eu gostaria de imprimir única linha que tem um valor máximo para uma determinada tag (o primeiro 'campo'). O exemplo acima é representativa de pelo de dados em que a saída vai ser classificados (como se tivesse sido canalizado através de um comando sort).

Foi útil?

Solução

Com base na minha para uma necessidade semelhante, este script mantém as coisas em ordem e não se acumula uma grande matriz. Ela imprime a linha com o valor mais alto de cada grupo.

#!/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
}

Outras dicas

Se você não precisar dos itens a ser na mesma ordem em que foram saída do meuprograma, os seguintes trabalhos:

... | awk '{ if ($2 > x[$1]) x[$1] = $2 } END { for (k in x) printf "%s %s", k, x[k] }'
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top