85 votes

compter les doublons dans une séquence triée à l'aide d'outils en ligne de commande

J'ai une commande (cmd1) qui parcourt un fichier journal pour filtrer un ensemble de chiffres. Les nombres sont dans un ordre aléatoire, j'utilise donc sort -gr pour obtenir une liste de nombres triés à l'envers. 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 vers laquelle je peux diriger la sortie ci-dessus, afin d'obtenir.. :

100     3
99      2
26      1
25      1
24      2

0 votes

0 votes

101voto

Comment ;

$ 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

1 votes

Je l'ai exécuté et il a produit une déclaration d'impression supplémentaire de 1,2 $ à la fin : 100 3 99 2 26 1 25 1 24 2 2 24

3 votes

L'exemple suivant ajoute une nouvelle ligne entre les résultats et supprime la ligne supplémentaire à la fin : 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}' | head -n -1 donc vous obtenez : 100 3 99 2 26 1 25 1 24 2

0 votes

Note sur la syntaxe, vous pouvez terminer une ligne avec un pipe au lieu d'utiliser une barre oblique inverse.

57voto

Ibrahim Points 627

uniq -c fonctionne pour GNU uniq 8.23 au moins, et fait exactement ce que vous voulez (en supposant une entrée triée).

10voto

ghostdog74 Points 86060

Si l'ordre n'est pas important

# 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

0 votes

+1 pour avoir fait ça avec 3 tuyaux en moins. Ce serait génial si vous pouviez élaborer sur la façon dont cela fonctionne car cela m'a rendu confus ;-) Merci.

9voto

ericcurtin Points 448

Triez numériquement les chiffres à l'envers, puis comptez les doublons, puis intervertissez les mots de gauche et de droite. Alignez-les en colonnes.

printf '%d\n' 100 99 26 25 100 24 100 24 99 \
   | sort -nr | uniq -c | awk '{printf "%-8s%s\n", $2, $1}'

100     3
99      2
26      1
25      1
24      2

2voto

Toby Speight Points 3930

En Bash, nous pouvons utiliser un tableau associatif pour compter les instances de chaque valeur d'entrée. En supposant que nous ayons 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 tableau a en utilisant le ++ opérateur mathématique sur les entrées du tableau concerné :

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 outil externe. sort des clés :

for i in $(printf '%s\n' "${!a[@]}" | sort -nr)
do
    echo "$i ${a[$i]}"
done

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X