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,
$ 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
-F,
Se divise en ,
NR>1
Traiter les lignes après la ligne 1arr[$1]++
Increment array arr
(divisé avec ,
) Avec la première colonne comme cléEND{}
Est exécuté à la fin du traitement du fichierfor (a in arr)
itération sur arr
avec la touche a
print a
Clé d'impression Tableau , arr[a]
Avec touche a
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
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
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] }