Aller au contenu
Administration Linux medium

Trier, compter et dédoublonner sous Linux

30 min de lecture

Vous avez la sortie de ps aux, un fichier de log Apache, ou une liste de paquets à analyser, et vous avez besoin de savoir qui apparaît le plus souvent, quelles lignes sont en double, combien il y a d'erreurs 404. Sous Linux, un pipeline de trois commandes suffit : sort pour ordonner, uniq pour dédoublonner, wc pour mesurer.

Ces outils font partie du socle Unix depuis les années 70. Ils sont présents sur tous les systèmes Linux sans installation. Leur vraie puissance est dans la composition : enchaînés, ils remplacent des scripts entiers en une seule ligne.

Vous avez vu les bases de sort, uniq et wc dans les fondamentaux. Ce guide couvre les options avancées et les patterns d'administration réels : tri sur colonne, stabilité, versions, comparaison de listes et analyse de logs.

  • Trier sur une colonne précise, par ordre numérique ou de version
  • Identifier les doublons, les lignes uniques, les plus fréquentes
  • Mesurer : lignes, mots, octets, caractères UTF-8
  • Comparer deux listes triées avec comm
  • Construire le pipeline sort | uniq -c | sort -rn pour analyser n'importe quel log

Un incident vient de se produire. Vous avez un access.log de 500 000 lignes et vous voulez savoir quelle IP a fait le plus de requêtes dans les 10 dernières minutes. Ou vous venez de migrer un paquet et vous voulez comparer la liste des services actifs avant et après. Ou vous auditez un système et vous cherchez les comptes utilisateurs qui apparaissent dans plusieurs fichiers à la fois. Dans ces situations, sort, uniq et comm font en 30 secondes ce qu'un script ferait en 30 lignes, et à moindre risque d'erreur. Ils sont aussi le socle de tout pipeline d'analyse de logs : dès que vous devez répondre à « combien de fois ? » ou « qui/quoi est en double ? », c'est ici que vous commencez.

sort lit son entrée en entier avant d'écrire quoi que ce soit : il charge les lignes, les ordonne, puis les restitue. Par défaut il compare les lignes caractère par caractère selon l'ordre de la locale, ce qui donne des résultats surprenants sur des nombres. Les options qui suivent portent toutes sur le même choix : quoi comparer (-k, -t) et comment comparer (-n, -V, -r).

Le piège le plus fréquent avec sort :

Fenêtre de terminal
printf "10\n2\n20\n1\n100\n" | sort
Sortie : tri alphabétique (défaut)
1
10
100
2
20

Sans option, sort trie comme du texte. 10 vient avant 2 parce que 1 < 2 en ASCII.

Fenêtre de terminal
printf "10\n2\n20\n1\n100\n" | sort -n
Sortie : tri numérique
1
2
10
20
100

L'option -n est indispensable dès que vous triez des nombres.

L'option -k choisit la colonne de tri. Par défaut, le séparateur est l'espace ou la tabulation.

Fenêtre de terminal
# Fichier scores.txt : "nom score"
sort -k2 -n scores.txt
Sortie
frank 60
bob 72
diana 72
charlie 88
alice 95
eve 95
  • -k2 : trier sur le deuxième champ
  • -n : tri numérique (sans ce flag, 60, 72, 88 seraient triés comme du texte)

Pour trier par ordre décroissant :

Fenêtre de terminal
sort -k2 -rn scores.txt
Sortie
eve 95
alice 95
charlie 88
diana 72
bob 72
frank 60

Trier sur une colonne avec un délimiteur personnalisé

Section intitulée « Trier sur une colonne avec un délimiteur personnalisé »

Utilisez -t pour définir le séparateur de champs :

Fenêtre de terminal
# Trier /etc/passwd par UID (champ 3, délimiteur :)
sort -t: -k3 -n /etc/passwd | head -5
Sortie
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync

C'est le même mécanisme que cut -d:, le duo sort -t: -k3 -n | cut -d: -f1,3 est très courant.

sort -u est l'équivalent de sort | uniq mais en plus efficace : il trie et supprime les doublons en une seule opération.

Fenêtre de terminal
sort -u fruits.txt
Sortie
apple
banana
cherry
date

Le tri alphabétique et le tri numérique donnent tous les deux de mauvais résultats pour des numéros de version comme v1.9, v1.10. L'option -V (version) les gère correctement :

Fenêtre de terminal
printf "v1.10\nv1.9\nv1.2\nv2.0\n" | sort -V
Sortie
v1.2
v1.9
v1.10
v2.0

Utile pour trier des tags Git, des noms de paquets ou des journaux versionnés.

Quand deux lignes ont la même valeur sur le champ de tri, sort peut les réordonnancer arbitrairement. L'option --stable garantit que leur ordre d'origine est préservé :

Fenêtre de terminal
sort -k2 -n --stable scores.txt

Les lignes bob 72 et diana 72 gardent l'ordre du fichier source, ce qui compte quand vous enchaînez des tris successifs.


uniq traite les répétitions consécutives. Il doit donc presque toujours être précédé de sort.

uniq -c remplace chaque groupe de lignes identiques par une seule ligne, précédée de son nombre d'occurrences. Le comptage porte sur la ligne entière, espaces compris.

Fenêtre de terminal
sort fruits.txt | uniq -c
Sortie
2 apple
3 banana
2 cherry
1 date

Le nombre à gauche est le compte d'occurrences. L'indentation variable est normale, c'est la largeur du plus grand nombre.

Combinez uniq -c avec sort -rn pour obtenir un classement :

Fenêtre de terminal
sort fruits.txt | uniq -c | sort -rn
Sortie
3 banana
2 cherry
2 apple
1 date

C'est le pattern top-N, probablement le pipeline le plus utilisé en analyse de logs Linux.

-d n'affiche qu'un exemplaire de chaque ligne répétée et masque tout le reste. Pratique pour repérer une entrée en double dans un fichier d'inventaire ou une liste d'utilisateurs.

Fenêtre de terminal
sort fruits.txt | uniq -d
Sortie
apple
banana
cherry

Seulement les lignes qui apparaissent plus d'une fois.

-u fait l'inverse de -d : il ne garde que les lignes sans aucune répétition. Attention au piège de nommage, ce -u n'a pas le même effet que le -u de sort, qui lui conserve une occurrence de chaque valeur.

Fenêtre de terminal
sort fruits.txt | uniq -u
Sortie
date

Seulement les lignes qui apparaissent exactement une fois.


wc (word count) compte des lignes, des mots ou des octets, selon l'option demandée. Sans option, il affiche les trois d'un coup. Sa force est de se placer en fin de pipeline : tout ce qui a survécu aux filtres précédents devient un nombre exploitable dans un script ou un rapport.

Ces trois options couvrent la quasi-totalité des besoins d'administration. Elles s'appliquent aussi bien à un fichier passé en argument qu'à l'entrée standard.

Fenêtre de terminal
wc -l fichier.txt # nombre de lignes
wc -w fichier.txt # nombre de mots
wc -c fichier.txt # nombre d'octets

wc accepte plusieurs fichiers et affiche un total :

Fenêtre de terminal
wc -l fruits.txt scores.txt access.log
Sortie
8 fruits.txt
6 scores.txt
8 access.log
22 total

Utile pour auditer rapidement la taille de fichiers de configuration ou de journaux.

-c compte les octets, -m compte les caractères (code points Unicode). La différence apparaît avec des caractères non-ASCII :

Fenêtre de terminal
echo "héllo" | wc -c # → 7 (é occupe 2 octets en UTF-8 + newline)
echo "héllo" | wc -m # → 6 (5 caractères + newline)

En administration Linux, -c est suffisant pour vérifier la taille d'un fichier. Utilisez -m uniquement si vous travaillez avec des fichiers contenant des caractères accentués ou des scripts non-latins.

wc -l à la fin d'un pipeline est une façon fiable de compter des résultats :

Fenêtre de terminal
# Combien d'utilisateurs avec un UID >= 1000 ?
awk -F: '$3 >= 1000' /etc/passwd | wc -l
# Combien de processus bob tourne en ce moment ?
ps aux | grep "^bob" | wc -l
# Combien de fichiers .conf dans /etc ?
find /etc -name "*.conf" | wc -l

comm compare deux fichiers ligne par ligne et affiche trois colonnes :

  • colonne 1 : lignes présentes uniquement dans le fichier 1
  • colonne 2 : lignes présentes uniquement dans le fichier 2
  • colonne 3 : lignes communes aux deux fichiers
Fenêtre de terminal
# list_a.txt : apple, banana, cherry
# list_b.txt : banana, cherry, date
comm <(sort list_a.txt) <(sort list_b.txt)
Sortie
apple
banana
cherry
date

Les options suppriment une colonne :

Fenêtre de terminal
# Intersection : lignes communes aux deux (supprimer colonnes 1 et 2)
comm -12 <(sort list_a.txt) <(sort list_b.txt)
Sortie
banana
cherry
Fenêtre de terminal
# Dans A seulement (supprimer colonnes 2 et 3)
comm -23 <(sort list_a.txt) <(sort list_b.txt)
Sortie
apple
Fenêtre de terminal
# Dans B seulement (supprimer colonnes 1 et 3)
comm -13 <(sort list_a.txt) <(sort list_b.txt)
Sortie
date

Comparer deux états d'un système est le cas d'usage le plus rentable de comm. Le principe : capturer une liste triée avant l'opération, la même après, puis demander à comm ce qui est apparu et ce qui a disparu. La sortie de dpkg --get-selections est déjà triée par nom, mais le sort explicite garantit le résultat quelle que soit la source.

Fenêtre de terminal
# Capturer l'état avant
dpkg --get-selections | awk '{print $1}' | sort > avant.txt
# ... après une opération ...
# Capturer l'état après
dpkg --get-selections | awk '{print $1}' | sort > apres.txt
# Paquets ajoutés
comm -13 avant.txt apres.txt
# Paquets supprimés
comm -23 avant.txt apres.txt

Les exemples qui suivent reposent tous sur la même mécanique : awk extrait une colonne, sort regroupe les valeurs identiques, uniq -c les compte, sort -rn classe du plus fréquent au plus rare. Seul le numéro de champ passé à awk change d'un cas à l'autre, car il dépend du format du journal analysé. Vérifiez ce numéro sur une ligne réelle avant de lancer l'analyse complète.

Le pattern sort | uniq -c | sort -rn s'applique à n'importe quelle colonne :

Fenêtre de terminal
# Top IPs dans un log d'accès
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
Sortie (lab)
3 192.168.1.10
3 192.168.1.5
2 192.168.1.20

Le même pipeline appliqué au champ du code de retour donne la répartition des réponses du serveur. Une proportion inhabituelle de 404 ou de 403 saute immédiatement aux yeux.

Fenêtre de terminal
awk '{print $4}' access.log | sort | uniq -c | sort -rn
Sortie (lab)
4 200
2 404
1 403
1 201

Classer les URL appelées indique où porter l'effort d'optimisation ou de mise en cache : les premières lignes concentrent en général l'essentiel du trafic.

Fenêtre de terminal
awk '{print $3}' access.log | sort | uniq -c | sort -rn
Sortie (lab)
4 /api/users
2 /api/products
2 /api/orders

Ici, pas de comptage : sort -t: -k3 -n classe /etc/passwd par UID croissant, tail -5 garde la fin du classement et cut ne conserve que le nom et l'identifiant. Utile pour repérer les derniers comptes créés sur une machine.

Fenêtre de terminal
sort -t: -k3 -n /etc/passwd | tail -5 | cut -d: -f1,3

ss -tn state established liste les connexions TCP établies. Attention au numéro de champ : dès qu'on filtre avec state, ss supprime la colonne State, et l'adresse distante se retrouve en quatrième position, pas en cinquième. NR>1 saute la ligne d'en-tête, cut -d: -f1 isole l'adresse du port, et le classement fait ressortir une IP qui ouvrirait un nombre anormal de sessions.

Fenêtre de terminal
ss -tn state established | awk 'NR>1 {print $4}' | cut -d: -f1 | sort | uniq -c | sort -rn

Les erreurs rencontrées avec ces trois commandes viennent presque toujours du même malentendu : elles comparent du texte, pas des valeurs. Un nombre mal trié, un doublon non détecté ou un comm incohérent se corrigent en précisant la nature de la donnée (-n, -V) ou en garantissant le tri en amont.

ProblèmeCause probableSolution
sort : les nombres sont mal ordonnésTri alphabétique par défautAjouter -n (numérique) ou -V (version)
uniq ne supprime pas tous les doublonsLignes non consécutivesPasser par sort avant uniq
comm : avertissements "not in sorted order"Fichiers non triésUtiliser comm <(sort f1) <(sort f2)
wc -l : résultat inférieur d'une unitéDernière ligne sans \nNormal, wc -l compte les newlines
sort -k2 : mauvais tri sur colonneTri alphabétique sur la colonneAjouter -n si la colonne contient des nombres
sort -u ne supprime pas toutCasse différente (Apple vs apple)Ajouter -f (ignore case) : sort -uf

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • sort -n est indispensable pour les nombres. Sans lui, 10 vient avant 2.
  • sort -k2 -n trie sur la deuxième colonne numériquement. -t: définit le délimiteur.
  • sort -V trie correctement les numéros de version (v1.9 avant v1.10).
  • sort -u = sort | uniq en une seule passe.
  • uniq -c compte les occurrences. uniq -d retourne les doublons. uniq -u retourne les uniques.
  • sort | uniq -c | sort -rn | head -N est le pipeline universel pour trouver les N éléments les plus fréquents.
  • comm exige des fichiers triés, toujours utiliser <(sort ...).
  • wc -c compte des octets, wc -m compte des caractères Unicode.
  • Référence awk : Aller plus loin sur l'extraction de colonnes et les conditions dans un pipeline.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn