Développement Web

Regex en ligne de commande : grep, sed et ripgrep

12 دقائق للقراءة

Sur un serveur, il n’y a pas d’interface graphique : juste un terminal et des fichiers de logs qui grossissent. C’est là que les regex deviennent un réflexe quotidien, à travers trois outils que tout sysadmin connaît — grep pour chercher, sed pour transformer, et ripgrep pour aller vite. Dans ce dernier tutoriel du parcours, on trie en direct les logs de Téranga Livraison depuis la ligne de commande, sans écrire une seule ligne de programme.

📍 Article principal du parcours : Maîtriser les expressions régulières : le guide complet
Ce tutoriel fait partie du parcours « Expressions régulières ». Commencez par le guide pour la vue d’ensemble.

🎯 Ce que vous allez apprendre

  • Chercher avec grep et ses options clés (-i, -n, -c, -v, -o, -r).
  • Comprendre la différence BRE / ERE, pourquoi grep -E change tout, et quand passer à grep -P.
  • Utiliser ripgrep (rg) pour sa vitesse et sa récursivité, et savoir où son moteur diffère de PCRE.
  • Transformer un flux de texte avec sed : substitution s///, rétroréférences, édition en place.

🛠️ Ce que vous allez construire

Un petit pipeline de triage : compter les erreurs par code de statut, extraire la liste des adresses IP fautives, et nettoyer un fichier d’export — le tout en quelques commandes enchaînées, directement sur le serveur.

Prérequis

  • Un terminal Linux ou macOS (ou WSL sous Windows). grep et sed sont préinstallés ; ripgrep s’installe via le gestionnaire de paquets.
  • Avoir parcouru au moins Les fondamentaux des regex.
  • Niveau : intermédiaire. ⏱️ ~35 minutes.

Étape 1 — grep, le réflexe de base

grep affiche les lignes d’un fichier qui contiennent un motif. C’est l’outil le plus utilisé du parcours d’un administrateur. Quelques options en font un couteau suisse : -i ignore la casse, -n ajoute le numéro de ligne, -c compte les lignes correspondantes, -v inverse (les lignes qui ne correspondent pas), -o n’affiche que la partie correspondante, et -r descend récursivement dans un dossier.

# Toutes les lignes d'erreur 500 du journal
grep " 500 " acces.log

# Compter les requêtes POST, sans tenir compte de la casse
grep -ic "POST" acces.log

# Lister les lignes SAUF celles qui renvoient un statut 200
grep -v " 200 " acces.log

Déjà, sans aucune syntaxe avancée, on filtre un journal de milliers de lignes en une commande. grep -c répond instantanément à « combien d’erreurs aujourd’hui ? ». La vraie puissance arrive quand on passe des chaînes littérales aux vraies expressions régulières — et là, une subtilité attend le débutant.

Point d’étape — Sur n’importe quel fichier texte, grep -n "mot" fichier.txt doit afficher les lignes contenant « mot », précédées de leur numéro. Si rien ne s’affiche, le mot n’est pas présent — testez avec un terme que vous savez là.

Étape 2 — BRE, ERE, et le piège du \d

Par défaut, grep utilise les expressions régulières basiques (BRE), un dialecte ancien où +, ?, {, }, (, ) et | ne sont pas des métacaractères : il faut les échapper avec un antislash pour leur donner leur pouvoir. C’est déroutant. L’option -E bascule en regex étendues (ERE), où ces symboles fonctionnent comme partout ailleurs.

# BRE (par défaut) : il faut échapper les accolades et le plus
grep "[0-9]\{1,3\}\.[0-9]\{1,3\}" acces.log

# ERE (-E) : la syntaxe redevient naturelle
grep -E "[0-9]{1,3}\.[0-9]{1,3}" acces.log

Deuxième piège, plus sournois : grep ne connaît pas \d, \w ni les raccourcis Perl, ni en BRE ni en ERE. À la place, on utilise les classes POSIX comme [[:digit:]] ou simplement [0-9]. Pour disposer de \d, du lookahead et des rétroréférences, il faut activer le moteur PCRE2 avec -P :

# Avec -P : la syntaxe Perl, donc \d, lookaround, etc.
grep -P "\d{1,3}(?:\.\d{1,3}){3}" acces.log

Petite note historique : les commandes egrep et fgrep que l’on voit dans de vieux tutoriels sont dépréciées ; les versions récentes de GNU grep affichent un avertissement et recommandent grep -E et grep -F à la place. Prenez tout de suite la bonne habitude.

Point d’étape — Comparez grep "428+" fichier et grep -E "428+" fichier sur une ligne contenant « 4288 ». Le premier cherche littéralement « 428+ » (avec le signe plus), le second cherche « 42 » suivi d’un ou plusieurs « 8 ». La bascule -E change tout.

Étape 3 — ripgrep : la vitesse et la récursivité

ripgrep (commande rg) est un grep moderne, écrit en Rust, devenu le favori des développeurs. Il est très rapide, récursif par défaut, et respecte automatiquement les fichiers .gitignore — pratique pour fouiller un projet sans bruit. Sa syntaxe de motif est, par défaut, celle du crate regex de Rust : proche d’ERE plus les raccourcis \d, \w.

# Chercher toutes les erreurs 5xx dans tous les logs du dossier (récursif)
rg "\" 5\d{2} " logs/

# N'afficher que la partie correspondante (les IP en tête de ligne)
rg -o "^\d{1,3}(?:\.\d{1,3}){3}" acces.log

Un point important hérité du tutoriel sur les groupes : le moteur par défaut de ripgrep ne gère ni les rétroréférences ni le lookaround. C’est un choix assumé : en s’appuyant sur des automates finis, il garantit un temps de recherche linéaire, sans risque d’explosion combinatoire. Quand vous avez réellement besoin de ces fonctions avancées, l’option -P bascule, comme pour grep, sur le moteur PCRE2 :

# Détecter un mot doublé : nécessite une rétroréférence, donc -P
rg -P "\b(\w+)\s+\1\b" acces.log

Au quotidien, le moteur par défaut suffit et reste le plus rapide. Ne sortez -P que pour le lookaround ou les rétroréférences, car PCRE2 perd la garantie de temps linéaire.

Étape 4 — sed : transformer un flux

Là où grep et rg cherchent, sed transforme. Sa commande reine est la substitution s/motif/remplacement/. Comme grep, sed utilise BRE par défaut et bascule en ERE avec -E. Les rétroréférences \1, \2 y réinjectent les groupes capturés, et l’esperluette & représente toute la correspondance.

# Remplacer le mot "commande" par "livraison" sur chaque ligne
sed "s/commande/livraison/g" notes.txt

# Réorganiser une date AAAA-MM-JJ en JJ/MM/AAAA (groupes + rétroréférences)
sed -E "s#([0-9]{4})-([0-9]{2})-([0-9]{2})#\3/\2/\1#g" export.csv

Deux détails de confort. D’abord, le séparateur de s n’est pas obligatoirement la barre oblique : ici on a choisi le dièse # pour éviter de devoir échapper les barres obliques de la date. Ensuite, le drapeau g en fin de commande applique le remplacement à toutes les occurrences de la ligne, pas seulement à la première. Pour modifier le fichier sur place plutôt que d’afficher le résultat, on ajoute -i — mais prudence, cette option écrit dans le fichier ; testez d’abord sans elle.

Point d’étape — Lancez la commande de date sur une ligne contenant « 2026-05-28 ». La sortie doit afficher « 28/05/2026 ». Si la date n’est pas transformée, vérifiez que vous avez bien mis -E : sans lui, les parenthèses devraient être échappées.

Étape 5 — Assembler un pipeline de triage

La force d’Unix, c’est d’enchaîner ces outils avec le tube | : la sortie de l’un devient l’entrée du suivant. Construisons un pipeline qui répond à une vraie question — « quelles IP ont provoqué des erreurs serveur, et combien de fois ? »

# 1. ne garder que les lignes en erreur 5xx
# 2. extraire l'IP en tête de chaque ligne
# 3. trier puis compter les occurrences uniques
grep -E "\" 5[0-9]{2} " acces.log | grep -oE "^[0-9]{1,3}(\.[0-9]{1,3}){3}" | sort | uniq -c | sort -rn

Lisons la chaîne. Le premier grep -E isole les lignes dont le statut est 5xx. Le second, avec -o, n’extrait que l’adresse IP en tête. sort regroupe les IP identiques, uniq -c les compte, et sort -rn classe du plus fréquent au moins fréquent. En une ligne, vous obtenez le palmarès des adresses qui plantent votre serveur — exactement le genre de diagnostic qu’on lance en pleine alerte. C’est l’aboutissement du parcours : les mêmes motifs qu’on a écrits à la main, puis exécutés en JavaScript et en Python, rendent ici un service immédiat sur le serveur.

Point d’étape — Sur un vrai fichier acces.log, ce pipeline doit afficher une liste « nombre — adresse IP », triée par fréquence décroissante. Si la sortie est vide, vérifiez d’abord que des erreurs 5xx existent avec grep -c -E "\" 5[0-9]{2} " acces.log.

Étape 6 — Bonus : awk, quand les champs comptent

Parfois, le texte est déjà découpé en colonnes par des espaces — c’est le cas d’une ligne d’access log. Là, awk complète idéalement le trio : il découpe chaque ligne en champs ($1, $2, …) et accepte une condition regex avec l’opérateur ~. On combine donc la précision des champs et la souplesse des motifs.

# Afficher l'IP (1er champ) des lignes dont le statut commence par 5
awk '$9 ~ /^5/ {print $1}' acces.log

# Compter le nombre total de requêtes POST
awk '/"POST /{n++} END {print n}' acces.log

Dans la première commande, $9 désigne le neuvième champ — le code de statut dans le format d’access log standard — et ~ /^5/ ne retient que ceux commençant par 5. Quand vos données sont tabulaires et régulières, cette approche par numéro de champ est souvent plus lisible qu’un long motif qui doit tout décrire. awk n’est pas un remplaçant de grep ou sed : c’est le bon outil quand la position d’un champ porte le sens, et il mérite une place dans la trousse aux côtés des trois autres.

🐞 Pièges fréquents

Symptôme Cause probable Correctif
grep cherche littéralement + ou {2} Mode BRE par défaut : ces symboles ne sont pas des métacaractères Ajouter -E (ERE) ou échapper : \+, \{2\}
\d ne reconnaît rien grep/sed ne connaissent pas les raccourcis Perl par défaut Utiliser [0-9] / [[:digit:]], ou grep -P
rg -P indisponible ripgrep compilé sans le support PCRE2 Installer une version avec PCRE2, ou reformuler sans lookaround
sed -i a tout écrasé Édition en place lancée sans test préalable Toujours tester sans -i d’abord ; garder une sauvegarde

🌍 Adaptation au contexte ouest-africain

Ces outils sont la trousse de secours du sysadmin sur un VPS modeste : ils ne consomment presque rien, fonctionnent en SSH sur la connexion la plus lente, et sont déjà installés sur toute distribution Linux. Quand une boutique en ligne hébergée à Dakar ralentit un vendredi soir, c’est un grep sur les logs — pas un tableau de bord cloud payant — qui révèle en dix secondes l’adresse qui martèle le serveur. ripgrep s’installe en un paquet et change la vie sur les gros projets ; mais même sans lui, grep et sed suffisent à 90 % des urgences.

✅ Récapitulatif

grep cherche (-i, -n, -c, -v, -o, -r) ; par défaut en BRE, passez en ERE avec -E, et en PCRE2 avec -P pour disposer de \d et du lookaround. ripgrep est rapide et récursif, avec son moteur linéaire par défaut et -P pour les fonctions avancées. sed transforme via s/motif/remplacement/g, avec -E, les rétroréférences \1 et l’édition en place -i. Enchaînés par le tube |, ils trient un journal entier en une ligne.

🧾 Aide-mémoire

Commande Rôle
grep -E "motif" f Chercher en regex étendues
grep -P "\d" f Chercher en PCRE2 (raccourcis Perl, lookaround)
grep -oc / -v / -n Partie seule / compter / inverser / numéroter
rg "motif" dossier/ Recherche rapide, récursive par défaut
rg -P "motif" ripgrep avec moteur PCRE2
sed -E "s/a/b/g" Substituer toutes les occurrences
sed -i ... Éditer le fichier en place (prudence)

💪 À vous de jouer

Écrivez une commande qui affiche, pour le fichier acces.log, la liste triée et dédupliquée des chemins (URL) ayant reçu au moins une requête.

Voir une solution
grep -oE "\"(GET|POST|PUT|DELETE) [^ ]+" acces.log | grep -oE "/[^ ]*" | sort -u

Le premier grep -o isole la méthode et le chemin ; le second ne garde que le chemin (à partir de la barre oblique) ; sort -u trie et supprime les doublons. On pourrait aussi le faire en une passe avec grep -P et un lookbehind, mais cette version reste portable partout.

Tutoriels frères

Pour aller plus loin

FAQ

Q : Faut-il préférer grep ou ripgrep ?
R : grep est partout, sans installation — idéal en SSH sur un serveur qu’on ne maîtrise pas. ripgrep est plus rapide et plus agréable sur un projet de code, grâce à la récursivité et au respect de .gitignore. Apprenez grep d’abord (il est universel), adoptez rg sur votre machine de travail.

Q : Pourquoi mon motif PCRE marche dans grep mais pas dans ripgrep ?
R : Sans -P, ripgrep utilise son moteur Rust, qui refuse le lookaround et les rétroréférences. Ajoutez -P pour passer à PCRE2 — mais souvenez-vous que vous perdez alors la garantie de temps linéaire qui fait la rapidité de ripgrep.

Q : sed -i se comporte différemment sur macOS, normal ?
R : Oui. La version BSD de sed (macOS) exige un argument après -i (souvent -i '' pour ne pas créer de sauvegarde), alors que la version GNU (Linux) accepte -i seul. C’est une différence classique à connaître quand on passe d’un système à l’autre.

Mots-clés : grep, sed, ripgrep, regex ligne de commande, grep -E, grep -P, BRE ERE, PCRE2, sed substitution, pipeline Unix.

مشاركة