Question

Je suis en train de filtrer la sortie d'un programme avec des commandes awk, et je suis presque là où j'ai besoin d'être. La commande à ce jour est la suivante:

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

Le dernier bit est le uniq d'un pauvre, qui n'est pas disponible sur ma cible. Étant donné les chances que la commande ci-dessus génère un résultat tel que celui-ci:

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

Ce que j'aimerais avoir, c'est ceci:

<*>

C’est-à-dire, je voudrais imprimer uniquement la ligne qui a une valeur maximale pour une balise donnée (le premier "champ"). L'exemple ci-dessus est représentatif des données at en ce que la sortie sera triée (comme si elle avait été acheminée via une commande sort ).

Était-ce utile?

La solution

Basé sur mon réponse à Un besoin similaire, ce script garde les choses en ordre et n'accumule pas un grand tableau. Il affiche la ligne avec la valeur la plus élevée de chaque groupe.

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

Autres conseils

Si vous n'avez pas besoin que les éléments soient dans le même ordre qu'ils ont été générés par myprogram, les opérations suivantes fonctionnent:

... | awk '{ if ($2 > x[$1]) x[$1] = $2 } END { for (k in x) printf "%s %s", k, x[k] }'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top