Dans l'environnement Linux, il est fréquent de devoir effectuer des statistiques de regroupement sur des données répétées, que ce soit dans des fichiers ou dans la sortie d'une commande. Cette tâche est également une question courante lors des entretiens techniques.
La méthode pour y parvenir est assez directe, reposant sur la combinaison des commandes clés : sort | uniq -c | sort -rn.
sort: Cette commande trie les lignes d'un fichier ou d'une entrée standard. Lorsqu'elle est utilisée sur une colonne spécifique, elle regroupe les lignes ayant des valeurs identiques dans cette colonne.uniq -c: La commandeuniqest conçue pour identifier et éliminer les lignes dupliquées consécutives. L'option-c(ou--count) permet de préfixer chaque ligne unique avec le nombre de ses occurrences.sort -rn: Après le comptage paruniq -c, une nouvelle opération de tri est nécessaire. L'option-ndesorteffectue un tri numérique (comparant les chaînes comme des nombres), tandis que l'option-rinverse l'ordre du tri, affichant les résultats du plus grand au plus petit.
Exemple 1 : Compter les mots dans un fichier texte
Soit un fichier nommé demo.txt contenant un mot par ligne. L'objectif est de trouver les 3 mots les plus fréquents.
Contenu de demo.txt :
hello
hi
hello
world
world
my
word
hi
hello
Commande pour obtenir les 3 mots les plus fréquents :
sort demo.txt | uniq -c | sort -rn | head -3
Résultat attendu :
3 hello
2 world
2 hi
Exemple 2 : Identifier les URL les plus demandées dans un log Nginx
Pour analyser un fichier access.log et déterminer les 10 URL les plus sollicitées.
Extrait d'un log Nginx :
1.2.3.4 - - [03/Jan/2013:21:17:20 -0600] ... GET /html/test.html HTTP/1.1 "200" ...
5.6.7.8 - - [03/Jan/2013:21:17:20 -0600] ... GET /html/test2.html HTTP/1.1 "200" ...
Une approche pour extraire et compter les URL (souvent la 14ème colonne dans un log Nginx au format par défaut) :
cat access.log | awk '{print $14}' | sort | uniq -c | sort -rn | head -10
Une méthode alternative utilisant le tri par colonne et l'extraction des résultats :
sort -k 14 access.log | uniq -c | sort -rn | head -10 | awk '{print $1,$15}'
Note : L'option -k de sort spécifie la colonne de tri. L'option -t permettrait de définir un délimiteur de colonne si nécessaire.
Résultat possible :
50 /index.html
45 /images/logo.png
...
Exemple 3 : Statistiques des états de connexion TCP sur le port 80
Utilisation de netstat pour visualiser les connexions actives, filtrage sur le port 80, puis analyse des états.
Sortie de netstat -nat | grep 80 (simplifiée) :
tcp 0 0 x.x.x.x:yyyy a.a.a.a:80 SYN_SENT
tcp 0 0 x.x.x.x:zzzz b.b.b.b:80 ESTABLISHED
tcp 0 0 x.x.x.x:wwww c.c.c.c:80 ESTABLISHED
tcp 0 0 x.x.x.x:vvvv d.d.d.d:80 CLOSE_WAIT
Commande pour compter les états de connexion :
netstat -nat | grep 80 | awk '{print $6}' | sort | uniq -c | sort -rn
Résultat attendu :
27 ESTABLISHED
10 LISTEN
2 CLOSE_WAIT
1 SYN_SENT