J'ai une commande (cmd1) qui parcourt un fichier journal pour filtrer un ensemble de nombres. Les nombres sont dans un ordre aléatoire, donc j'utilise sort -gr pour obtenir une liste triée inversée de nombres. Il peut y avoir des doublons dans cette liste triée. J'ai besoin de trouver le nombre de chaque numéro unique dans cette liste.
Par exemple si la sortie de cmd1 est:
100
100
100
99
99
26
25
24
24
J'ai besoin d'une autre commande à laquelle je peux diriger la sortie ci-dessus, pour que j'obtienne:
100 3
99 2
26 1
25 1
24 2
que diriez-vous;
$ echo "100 100 100 99 99 26 25 24 24" \
| tr " " "\n" \
| sort \
| uniq -c \
| sort -k2nr \
| awk '{printf("%s\t%s\n",$2,$1)}END{print}'
Le résultat est :
100 3
99 2
26 1
25 1
24 2
uniq -c
fonctionne pour GNU uniq 8.23 au moins, et fait exactement ce que vous voulez (en supposant une entrée triée).
si la commande n'est pas importante
# echo "100 100 100 99 99 26 25 24 24" | awk '{for(i=1;i<=NF;i++)a[$i]++}END{for(o in a) printf "%s %s ",o,a[o]}'
26 1 100 3 99 2 24 2 25 1
Triez les nombres en sens inverse, puis comptez les doublons, puis échangez les mots gauche et droit. Alignez dans les colonnes.
printf '%d\n' 100 99 26 25 100 24 100 24 99 \
| sort | uniq -c | sort -nr | awk '{printf "%-8s%s\n", $2, $1}'
100 3
99 2
26 1
25 1
24 2
Dans Bash, nous pouvons utiliser un tableau associatif pour compter les instances de chaque valeur d'entrée. En supposant que nous avons la commande $cmd1
, par exemple.
#!/bin/bash
cmd1='printf %d\n 100 99 26 25 100 24 100 24 99'
Ensuite, nous pouvons compter les valeurs dans la variable de tableau a
en utilisant le ++
opérateur mathématique sur les entrées de tableau pertinentes:
while read i
do
((++a["$i"]))
done < <($cmd1)
Nous pouvons imprimer les valeurs résultantes:
for i in "${!a[@]}"
do
echo "$i ${a[$i]}"
done
Si l'ordre de sortie est important, nous pourrions avoir besoin d'un sort
externe des clés:
for i in $(printf '%s\n' "${!a[@]}" | sort -nr)
do
echo "$i ${a[$i]}"
done