Linux sans magie #25 — grep, cut, sort, uniq et wc : extraire et filtrer efficacement du texte
Apprendre à combiner grep, cut, sort, uniq et wc pour filtrer, extraire, trier, compter et résumer des données texte dans des pipelines Linux simples et lisibles.
Dans l’article précédent, nous avons vu comment stdin, stdout, stderr, les redirections et les pipes permettent de faire circuler des données entre les commandes.
Cette fois, nous allons utiliser ce mécanisme pour réaliser un travail très courant sous Linux : prendre un flux texte et le réduire progressivement jusqu’à obtenir l’information utile.
Cinq commandes suffisent déjà pour construire de nombreux traitements pratiques :
greppour sélectionner des lignes ;cutpour extraire des champs ;sortpour trier ;uniqpour regrouper des lignes identiques adjacentes ;wcpour compter.
L’objectif n’est pas d’apprendre une longue liste d’options. Il est de comprendre comment chaque commande transforme un flux, puis comment les assembler dans un pipeline lisible.
Le principe : une commande, une transformation
Un pipeline Unix devient plus facile à comprendre si chaque étape répond à une seule question.
Prenons ce fichier de laboratoire :
2026-09-18 alice INFO connexion
2026-09-18 bob ERROR disque
2026-09-18 alice ERROR réseau
2026-09-18 claire INFO connexion
2026-09-18 bob ERROR disque
2026-09-18 alice INFO déconnexion
Nous allons l’enregistrer dans evenements.log :
cat > evenements.log <<'EOF'
2026-09-18 alice INFO connexion
2026-09-18 bob ERROR disque
2026-09-18 alice ERROR réseau
2026-09-18 claire INFO connexion
2026-09-18 bob ERROR disque
2026-09-18 alice INFO déconnexion
EOF
Le fichier est volontairement simple : les champs sont séparés par des espaces et chaque ligne suit la même structure.
Avant de construire un pipeline, il faut savoir ce que l’on cherche. Par exemple :
Quels utilisateurs apparaissent dans les événements
ERROR, et combien de fois chacun apparaît-il ?
Nous pouvons résoudre ce problème étape par étape.
grep : sélectionner les lignes utiles
grep lit du texte et sélectionne les lignes qui correspondent à un motif.
Pour afficher uniquement les erreurs :
grep 'ERROR' evenements.log
Résultat attendu :
2026-09-18 bob ERROR disque
2026-09-18 alice ERROR réseau
2026-09-18 bob ERROR disque
Le point important est que grep ne transforme pas ici les lignes : il décide seulement lesquelles passent à l’étape suivante.
Dans un pipeline, la même commande peut lire depuis stdin :
cat evenements.log | grep 'ERROR'
Cette écriture fonctionne, mais lorsque grep sait lire directement un fichier, la forme suivante est plus simple :
grep 'ERROR' evenements.log
Le pipe devient utile lorsque l’entrée provient réellement d’une autre commande.
Ignorer la casse avec grep -i
L’option -i demande à grep d’ignorer les différences de casse lors de la correspondance.
Exemple :
printf 'Error\nERROR\nerreur\n' | grep -i 'error'
Les deux premières lignes correspondent au motif error sans tenir compte de la casse.
Cette option peut être utile sur des fichiers dont la capitalisation n’est pas homogène.
Exclure des lignes avec grep -v
L’option -v inverse la sélection : elle conserve les lignes qui ne correspondent pas au motif.
Pour éliminer les événements INFO :
grep -v 'INFO' evenements.log
Dans notre fichier, cela revient ici à conserver les événements ERROR.
Le rôle reste le même : grep travaille au niveau de la ligne.
cut : extraire un champ
Après avoir sélectionné les lignes d’erreur, nous voulons uniquement le nom de l’utilisateur.
Dans notre fichier, le deuxième champ contient le nom :
2026-09-18 bob ERROR disque
^^^
cut permet de sélectionner un champ lorsqu’un séparateur simple est connu.
Exemple :
cut -d' ' -f2 evenements.log
Ici :
-d' 'définit l’espace comme séparateur ;-f2sélectionne le deuxième champ.
Résultat :
alice
bob
alice
claire
bob
alice
Nous pouvons maintenant combiner grep et cut :
grep 'ERROR' evenements.log | cut -d' ' -f2
Résultat :
bob
alice
bob
Le raisonnement est simple :
grep → conserve les lignes ERROR
cut → extrait le deuxième champ
Limite importante de cut
cut fonctionne bien lorsque le séparateur est simple et régulier.
Avec -d' ', plusieurs espaces consécutifs peuvent rendre le découpage moins intuitif, car chaque caractère séparateur compte.
Par conséquent, cut est adapté à des formats simples et prévisibles, mais il ne faut pas le présenter comme un parseur universel.
Pour des formats plus complexes ou structurés, d’autres outils sont souvent plus appropriés. Ils restent hors périmètre de cet article.
sort : trier les lignes
Reprenons la sortie précédente :
bob
alice
bob
Pour la trier :
grep 'ERROR' evenements.log | cut -d' ' -f2 | sort
Résultat :
alice
bob
bob
Par défaut, sort trie les lignes selon les règles de comparaison de l’environnement courant.
Pour notre lab avec des noms simples, cela suffit.
Le tri n’est pas seulement esthétique. Il prépare aussi les données pour uniq.
uniq : traiter les doublons adjacents
Une erreur fréquente consiste à penser que uniq cherche tous les doublons n’importe où dans un fichier.
En réalité, uniq travaille sur des lignes identiques adjacentes.
Avec :
bob
alice
bob
un simple :
uniq
ne regrouperait pas les deux lignes bob, car elles ne sont pas voisines.
C’est pourquoi on utilise très souvent :
sort | uniq
Dans notre pipeline :
grep 'ERROR' evenements.log | cut -d' ' -f2 | sort | uniq
Résultat :
alice
bob
Nous avons maintenant la liste des utilisateurs ayant généré au moins un événement ERROR.
Compter les occurrences avec uniq -c
L’option -c ajoute le nombre d’occurrences de chaque groupe de lignes identiques adjacentes.
Exécutez :
grep 'ERROR' evenements.log | cut -d' ' -f2 | sort | uniq -c
Résultat attendu :
1 alice
2 bob
Nous avons donc répondu à la question initiale :
aliceapparaît une fois dans les événementsERROR;bobapparaît deux fois.
Chaque étape garde une responsabilité précise.
Lire le pipeline de gauche à droite
Le pipeline complet est :
grep 'ERROR' evenements.log | cut -d' ' -f2 | sort | uniq -c
Il faut le lire ainsi :
evenements.log
↓
grep 'ERROR'
↓
lignes d'erreur uniquement
↓
cut -d' ' -f2
↓
noms d'utilisateurs
↓
sort
↓
noms regroupés par ordre
↓
uniq -c
↓
nombre d'occurrences par utilisateur
Cette méthode de lecture est plus importante que la mémorisation de la ligne complète.
Si le résultat est faux, il suffit d’exécuter le pipeline progressivement jusqu’à trouver l’étape qui ne produit pas ce que l’on attend.
wc : compter des lignes
wc peut compter plusieurs éléments d’un flux. Dans cet article, nous utilisons surtout wc -l, qui compte les lignes.
Pour savoir combien d’événements ERROR sont présents :
grep 'ERROR' evenements.log | wc -l
Résultat :
3
Le fonctionnement est direct :
grep sélectionne trois lignes
↓
wc -l compte ces trois lignes
Pour compter le nombre d’utilisateurs distincts ayant produit une erreur :
grep 'ERROR' evenements.log | cut -d' ' -f2 | sort | uniq | wc -l
Résultat :
2
Cette fois, wc -l compte la sortie de uniq, pas celle de grep.
Compter sans perdre le sens du pipeline
Deux pipelines très proches peuvent répondre à deux questions différentes.
Nombre total d’erreurs :
grep 'ERROR' evenements.log | wc -l
Nombre d’utilisateurs distincts concernés :
grep 'ERROR' evenements.log | cut -d' ' -f2 | sort | uniq | wc -l
Le dernier outil est le même, mais les données qui lui arrivent ne sont plus les mêmes.
C’est une règle générale : la signification du résultat dépend de ce que chaque étape a déjà transformé.
Un deuxième exemple : compter les types d’événements
Supposons que nous voulions connaître la fréquence des niveaux INFO et ERROR.
Le niveau est le troisième champ.
Nous pouvons donc écrire :
cut -d' ' -f3 evenements.log | sort | uniq -c
Résultat attendu :
3 ERROR
3 INFO
Ici, grep n’est pas nécessaire, car nous voulons conserver toutes les lignes.
Le meilleur pipeline n’est pas celui qui utilise le plus de commandes : c’est celui qui exprime clairement la transformation nécessaire.
Éviter le cat inutile
Une construction fréquente est :
cat evenements.log | grep 'ERROR'
Elle fonctionne, mais grep sait déjà lire directement un fichier :
grep 'ERROR' evenements.log
Cela ne signifie pas que cat est inutile en général.
Il devient pertinent lorsqu’on veut réellement concaténer plusieurs fichiers ou produire un flux dans une situation où cette étape apporte quelque chose.
Le principe à retenir est simplement : ne pas ajouter une commande si elle n’effectue aucune transformation utile.
Diagnostiquer un pipeline étape par étape
Lorsqu’un pipeline devient plus long, évitez de corriger toute la ligne à l’aveugle.
Commencez par la première étape :
grep 'ERROR' evenements.log
Puis ajoutez la suivante :
grep 'ERROR' evenements.log | cut -d' ' -f2
Puis :
grep 'ERROR' evenements.log | cut -d' ' -f2 | sort
Puis enfin :
grep 'ERROR' evenements.log | cut -d' ' -f2 | sort | uniq -c
Cette progression permet de vérifier le contenu du flux après chaque transformation.
C’est particulièrement utile lorsqu’un fichier réel contient des séparateurs inattendus, des lignes vides ou des formats hétérogènes.
Bonnes pratiques
Gardez les pipelines courts et lisibles.
Si une chaîne devient difficile à comprendre, testez ou documentez chaque étape séparément.
Ne supposez pas qu’un fichier texte est parfaitement régulier. Avant d’utiliser cut, examinez quelques lignes :
head evenements.log
Vérifiez également si les espaces, tabulations ou délimiteurs sont homogènes.
Pour uniq, retenez la règle fondamentale : les lignes identiques doivent être adjacentes pour être regroupées. Si vous cherchez des valeurs uniques dans un flux non trié, sort | uniq est une construction courante.
Enfin, distinguez toujours le nombre total de lignes du nombre de valeurs distinctes. wc -l compte uniquement ce qu’il reçoit.
Sécurité et limites
Les commandes utilisées ici sont essentiellement des outils de lecture et de transformation de texte.
Elles deviennent toutefois capables de modifier des fichiers si leur sortie est redirigée avec > ou >>.
Par exemple :
grep 'ERROR' evenements.log > erreurs.log
crée ou remplace erreurs.log.
Comme vu dans l’article précédent, vérifiez donc toujours la destination d’une redirection avant d’utiliser un fichier important.
Évitez aussi d’utiliser des pipelines textuels naïfs pour traiter des formats structurés complexes lorsque la structure elle-même doit être respectée. Un fichier JSON, YAML ou CSV avec échappements et guillemets mérite généralement un outil adapté à son format.
Ce que nous ne couvrons pas encore
Nous restons volontairement sur les fonctions essentielles.
Nous ne détaillons pas ici :
- les expressions régulières avancées ;
grep -Pet les particularités PCRE ;awk;sed;- les clés de tri avancées de
sort; - les règles de locale en profondeur ;
- les séparateurs complexes ;
- le traitement robuste de CSV, JSON ou YAML ;
- les pipelines sophistiqués de plusieurs dizaines d’étapes.
Le but est de maîtriser d’abord les briques de base et leur circulation dans un pipeline.
Nettoyage du lab
Si vous avez travaillé dans un répertoire dédié, supprimez simplement le fichier créé :
rm -f evenements.log
Si d’autres fichiers de test ont été créés, vérifiez leur nom avant suppression.
Références officielles
- GNU Grep Manual — GNU Project
- GNU Coreutils Manual — cut — GNU Project
- GNU Coreutils Manual — sort — GNU Project
- GNU Coreutils Manual — uniq — GNU Project
- GNU Coreutils Manual — wc — GNU Project
Conclusion
grep, cut, sort, uniq et wc deviennent réellement utiles lorsqu’on les considère comme des transformations successives plutôt que comme des commandes isolées.
Le modèle de base est simple :
grep → choisir les lignes
cut → choisir les champs
sort → ordonner
uniq → regrouper les doublons adjacents
wc → compter
Un pipeline comme :
grep 'ERROR' evenements.log | cut -d' ' -f2 | sort | uniq -c
n’est alors plus une formule à mémoriser. C’est une succession de décisions lisibles : filtrer les erreurs, extraire l’utilisateur, regrouper les noms identiques puis compter leurs occurrences.
Cette manière de raisonner constitue une base solide avant d’aborder des outils de traitement de texte plus puissants.
