web-dev-qa-db-fra.com

Groupe Awk / Unix par

avoir ce fichier texte:

name, age
joe,42
jim,20
bob,15
mike,24
mike,15
mike,54
bob,21

Essayer d'obtenir ceci (nombre):

joe 1
jim 1
bob 2
mike 3

Merci,

31
John Williams
$ awk -F, 'NR>1{arr[$1]++}END{for (a in arr) print a, arr[a]}' file.txt
joe 1
jim 1
mike 3
bob 2

EXPLICATIONS

  • -F, Se divise en ,
  • NR>1 Traiter les lignes après la ligne 1
  • arr[$1]++ Increment array arr (divisé avec ,) Avec la première colonne comme clé
  • Le bloc END{} Est exécuté à la fin du traitement du fichier
  • for (a in arr) itération sur arr avec la touche a
  • print a Clé d'impression Tableau , arr[a] Avec touche a
69
Gilles Quenot

Supprimez la ligne d'en-tête, supprimez le champ d'âge, regroupez les mêmes noms (tri), comptez les exécutions identiques, sortez au format souhaité.

tail -n +2 txt.txt | cut -d',' -f 1 | sort | uniq -c | awk '{ print $2, $1 }'

production

bob 2
jim 1
joe 1
mike 3
25
nneonneo

Il semble que vous souhaitiez une sortie triée. Vous pouvez simplement diriger ou imprimer dans sort -nk 2:

awk -F, 'NR>1 { a[$1]++ } END { for (i in a) print i, a[i] | "sort -nk 2" }' file

Résultats:

jim 1
joe 1
bob 2
mike 3

Cependant, si vous avez GNU awk installé, vous pouvez effectuer le tri sans coreutils. Voici la solution à processus unique qui triera le tableau selon ses valeurs. La solution devrait encore être assez rapide. Courez comme:

awk -f script.awk file

Contenu de script.awk:

BEGIN {
    FS=","
}

NR>1 {
    a[$1]++
}

END {
    for (i in a) {
        b[a[i],i] = i
    }

    n = asorti(b)

    for (i=1;i<=n;i++) {
        split (b[i], c, SUBSEP)
        d[++x] = c[2]
    }

    for (j=1;j<=n;j++) {
        print d[j], a[d[j]]
    }
}

Résultats:

jim 1
joe 1
bob 2
mike 3

Alternativement, voici le one-liner:

awk -F, 'NR>1 { a[$1]++ } END { for (i in a) b[a[i],i] = i; n = asorti(b); for (i=1;i<=n;i++) { split (b[i], c, SUBSEP); d[++x] = c[2] } for (j=1;j<=n;j++) print d[j], a[d[j]] }' file
8
Steve

Une solution strictement awk ...

BEGIN { FS = "," }
{ ++x[$1] }
END { for(i in x) print i, x[i] }

Si name, age est vraiment dans le fichier, vous pouvez ajuster le programme awk pour l'ignorer ...

BEGIN   { FS = "," }
/[0-9]/ { ++x[$1] }
END     { for(i in x) print i, x[i] }
4
DigitalRoss