web-dev-qa-db-fra.com

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

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
69
letronje

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
84

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

44
Ibrahim

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
10
ghostdog74

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
5
ericcurtin

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
2
Toby Speight