Domanda

Sto eseguendo il piping dell'output di un programma tramite alcuni comandi awk e sono quasi dove devo essere. Il comando finora è:

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
]++'

L'ultimo bit è il uniq di un uomo povero, che non è disponibile sul mio obiettivo. Data la possibilità che il comando sopra produca un output come questo:

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

Quello che mi piacerebbe avere è questo:

<*>

Cioè, vorrei stampare solo la riga che ha un valore massimo per un determinato tag (il primo 'campo'). L'esempio sopra è rappresentativo dei dati at in quanto l'output verrà ordinato (come se fosse stato reindirizzato tramite un comando sort ).

È stato utile?

Soluzione

Basato sulla mia risposta a un'esigenza simile, questo script mantiene le cose in ordine e non accumula un grande array. Stampa la linea con il valore più alto di ciascun gruppo.

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

Altri suggerimenti

Se non è necessario che gli articoli siano nello stesso ordine in cui sono stati prodotti dal myprogram, le seguenti operazioni:

... | awk '{ if ($2 > x[$1]) x[$1] = $2 } END { for (k in x) printf "%s %s", k, x[k] }'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top