Tutoriel

grep, sed et awk : exemples de traitement de texte dans le terminal Linux

Mis à jour: · Skillaria.Top

grep trouve les lignes qui correspondent à un motif (grep -rn error /var/log), sed modifie le texte dans un flux ou dans un fichier (sed -i 's/old/new/g' file), et awk travaille sur les colonnes et fait des calculs (awk '{print $1}' access.log). Combinés dans un pipeline, ils remplacent un script : grep filtre les lignes, sed corrige le texte, awk découpe les champs et agrège.

grep, sed et awk sont trois utilitaires classiques de Linux pour traiter du texte. grep trouve les lignes qui correspondent à un motif, sed remplace et supprime du texte dans un flux sans ouvrir d'éditeur, et awk découpe une ligne en colonnes et sait compter. Voici des exemples grep, sed et awk qui servent réellement lors de l'analyse de logs, de fichiers de configuration et de sorties de commandes, ainsi que les erreurs les plus fréquentes.

Quand utiliser quel outil

Les trois outils lisent le texte ligne par ligne et écrivent le résultat sur la sortie standard, ce qui permet de les enchaîner facilement avec |. La différence tient à la tâche que chacun résout le mieux.

TâcheOutilExemple
Trouver des lignes contenant un textegrepgrep ERROR app.log
Remplacer un textesedsed 's/http:/https:/g' file
Supprimer ou afficher des lignes par numérosedsed -n '10,20p' file
Extraire une colonneawkawk '{print $1}' access.log
Calculer une somme, une moyenne, un regroupementawkawk '{s+=$10} END {print s}'

Règle simple : si vous voulez seulement filtrer, prenez grep ; si vous voulez modifier le texte, prenez sed ; si le texte contient des colonnes ou qu'il faut faire de l'arithmétique, prenez awk.

grep : recherche de lignes par motif

Exemples grep de base

# Lignes contenant le mot error dans le fichier
grep error /var/log/syslog

# Sans tenir compte de la casse : Error, ERROR, error
grep -i error app.log

# Avec les numéros de ligne
grep -n "Connection refused" app.log

# Récursivement dans un répertoire, avec les noms de fichiers
grep -rn "DB_HOST" /etc/myapp/

# Uniquement les noms de fichiers contenant une correspondance
grep -rl "TODO" src/

# Inverser : tout SAUF les commentaires et les lignes vides
grep -v -e '^#' -e '^$' /etc/ssh/sshd_config

# Compter le nombre de lignes correspondantes
grep -c " 500 " access.log

L'option -w recherche un mot entier : grep -w log ne trouvera pas login. L'option -F désactive les expressions régulières et recherche la chaîne telle quelle, ce qui est pratique quand le motif contient des points, des parenthèses ou des astérisques.

Contexte autour de la ligne trouvée

Une erreur dans un log est rarement compréhensible à partir d'une seule ligne : il faut la pile d'appels ou la requête qui l'a provoquée. Pour cela, il existe des options de contexte :

# 3 lignes après la correspondance (After)
grep -A 3 "Traceback" app.log

# 2 lignes avant (Before)
grep -B 2 "OOM" /var/log/kern.log

# 5 lignes de chaque côté (Context)
grep -C 5 "segfault" /var/log/syslog

grep sépare les groupes de correspondances par une ligne --, ce qui rend la sortie facile à lire.

grep et les expressions régulières

Par défaut, grep comprend les expressions régulières de base (BRE). Avec l'option -E, on active les expressions étendues (ERE), où +, ?, | et les parenthèses fonctionnent sans antislash.

ConstructionSignificationExemple
^début de lignegrep '^root' /etc/passwd
$fin de lignegrep 'bash$' /etc/passwd
.n'importe quel caractèregrep 'h.t'
*0 répétition ou plusgrep 'ab*c'
+ (ERE)1 répétition ou plusgrep -E '[0-9]+'
| (ERE)ougrep -E 'error|warn'
[...]un caractère parmi l'ensemblegrep '[Ee]rror'
# Lignes contenant des erreurs ou des avertissements
grep -E "ERROR|WARN" app.log

# Seulement les adresses IP du log, une par ligne (-o affiche uniquement la correspondance)
grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log

grep -P : extraire une valeur entre des éléments connus

GNU grep propose l'option -P, qui accepte les expressions régulières au style Perl. Elle fournit \K (« oublier tout ce qui a été trouvé jusqu'ici ») et l'anticipation, ce qui permet de n'extraire que la valeur :

$ echo 'user_id=4821 status=ok' | grep -oP 'user_id=\K[0-9]+'
4821

$ grep -oP '"version":\s*"\K[^"]+' package.json
2.4.1

L'option -P n'existe pas dans toutes les versions de grep (par exemple, grep de BSD sur macOS ne la propose pas) ; dans les scripts portables, mieux vaut utiliser sed ou awk.

grep -q dans les conditions des scripts

grep -q n'affiche rien et renvoie seulement un code de sortie : 0 si trouvé, 1 sinon. La vérification s'écrit ainsi directement dans un if :

if grep -q "^PermitRootLogin no" /etc/ssh/sshd_config; then
  echo "connexion root désactivée"
fi

C'est plus court que d'enregistrer la sortie dans une variable pour tester si elle est vide, et grep s'arrête à la première correspondance.

sed : remplacement et suppression de texte

Remplacement : la commande s

La commande principale de sed est s/motif/remplacement/options. Sans l'option g, seule la première correspondance de chaque ligne est remplacée.

# Afficher le texte avec le remplacement (le fichier ne change pas)
sed 's/foo/bar/' file.txt

# Remplacer toutes les occurrences dans la ligne
sed 's/foo/bar/g' file.txt

# Sans tenir compte de la casse (GNU sed)
sed 's/error/ERROR/gI' app.log

# Autre délimiteur si le texte contient des slashs
sed 's|/var/www|/srv/www|g' nginx.conf

sed -i : remplacement directement dans le fichier

L'option -i réécrit le résultat dans le fichier. Pour ne pas perdre l'original, indiquez un suffixe de sauvegarde :

# Crée config.ini.bak et modifie config.ini
sed -i.bak 's/^debug=true/debug=false/' config.ini

# Remplacement dans tous les .conf d'un répertoire
find /etc/myapp -name "*.conf" -exec sed -i 's/old-host/new-host/g' {} +

Avant une modification de masse, lancez d'abord la commande sans -i et examinez le résultat. Sur macOS (sed de BSD), l'option -i exige un argument : sed -i '' 's/a/b/' file.

Travailler sur des lignes par numéro ou par motif

# Afficher les lignes 10 à 20 (-n désactive l'affichage automatique, p — affichage)
sed -n '10,20p' file.txt

# Supprimer la ligne 5
sed '5d' file.txt

# Supprimer la dernière ligne
sed '$d' file.txt

# Supprimer les lignes vides et les commentaires
sed -e '/^$/d' -e '/^#/d' nginx.conf

# Remplacer uniquement dans les lignes contenant "listen"
sed '/listen/s/80/8080/' nginx.conf

# Insérer une ligne après une correspondance (GNU sed)
sed '/^\[mysqld\]/a max_connections = 500' my.cnf

Références arrière et &

Une partie du motif entre parenthèses peut être réutilisée dans le remplacement via \1, \2, et le symbole & désigne tout le texte trouvé.

# Inverser le nom et le prénom (ERE avec -E)
$ echo "Ivanov Piotr" | sed -E 's/(\S+) (\S+)/\2 \1/'
Piotr Ivanov

# Entourer tous les nombres de crochets
$ echo "port 8080, timeout 30" | sed -E 's/[0-9]+/[&]/g'
port [8080], timeout [30]

# Transformer la date 2026-10-14 en 14.10.2026
$ echo 2026-10-14 | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3.\2.\1/'
14.10.2026

awk : colonnes, conditions et calculs

Afficher la colonne voulue

awk découpe chaque ligne en champs à partir des espaces et des tabulations : $1 est le premier champ, $2 le deuxième, $NF le dernier, $0 la ligne entière.

# Adresses IP du log nginx (première colonne)
awk '{print $1}' /var/log/nginx/access.log

# Nom d'utilisateur et shell depuis /etc/passwd (séparateur — deux-points)
awk -F: '{print $1, $7}' /etc/passwd

# Dernière colonne
df -h | awk '{print $NF}'

# Séparateur de sortie personnalisé
awk -F: -v OFS=';' '{print $1, $3}' /etc/passwd

Conditions : n'afficher que les lignes nécessaires

Avant le bloc entre accolades, on peut placer une condition : awk n'exécute l'action que pour les lignes qui y correspondent.

# Utilisateurs dont l'UID est à partir de 1000 (utilisateurs ordinaires, pas système)
awk -F: '$3 >= 1000 {print $1}' /etc/passwd

# Requêtes avec le code de réponse 500 ou plus (9e champ au format combined)
awk '$9 >= 500' access.log

# Lignes dont la 6e colonne correspond à une expression régulière
awk '$6 ~ /POST/' access.log

# Fichiers de plus de 100 Mo d'après la sortie de ls -l
ls -l | awk '$5 > 100*1024*1024 {print $9}'

BEGIN, END et NR : awk comme petit programme

Le bloc BEGIN s'exécute avant la lecture de la première ligne, END après la dernière. NR contient le numéro de la ligne courante, et dans le bloc END — leur nombre total.

# Somme des tailles de réponses (10e champ) en mégaoctets
awk '{sum += $10} END {printf "%.1f Mo\n", sum/1024/1024}' access.log

# Temps de réponse moyen d'après la dernière colonne
awk '{s += $NF} END {if (NR) print s/NR}' timings.log

# Ignorer l'en-tête d'un CSV
awk -F, 'NR > 1 {print $2}' users.csv

# Compter les requêtes par IP : tableau associatif
awk '{count[$1]++} END {for (ip in count) print count[ip], ip}' access.log | sort -rn | head

Le dernier exemple est classique pour l'analyse de logs : le tableau count, indexé par l'IP, remplace l'enchaînement sort | uniq -c et se prête facilement à des extensions, par exemple au total du trafic pour chaque adresse.

Pipelines : grep, sed et awk ensemble

La vraie puissance apparaît dans la combinaison. Chaque outil fait sa part, et | transmet le résultat au suivant.

Top 10 des IP avec erreurs 5xx

grep ' 50[0-9] ' /var/log/nginx/access.log \
  | awk '{print $1}' \
  | sort | uniq -c | sort -rn | head -10
    412 203.0.113.45
    118 198.51.100.7
     36 192.0.2.19

Ici grep élimine grossièrement les lignes, awk extrait le champ, et sort | uniq -c compte les répétitions. On peut aussi tout faire avec un seul awk : awk '$9 ~ /^5/ {c[$1]++} END {for (i in c) print c[i], i}' access.log | sort -rn | head — c'est plus précis, car on vérifie directement la colonne du code de réponse.

Quelles URL sont ouvertes le plus souvent

awk '{print $7}' access.log | sed 's/?.*//' | sort | uniq -c | sort -rn | head

sed coupe ici la partie query-string, afin que /search?q=a et /search?q=b soient comptés comme une seule page.

Valeurs d'une configuration sans commentaires

grep -v '^\s*#' /etc/myapp/app.env | grep '=' | awk -F= '{print $1}'

Erreurs survenues à une heure précise

grep '14/Oct/2026:03:' access.log | awk '$9 >= 500 {print $4, $7, $9}'

Erreurs typiques

  • Guillemets doubles au lieu de simples dans awk. Dans awk "{print $1}", le shell remplace $1 par sa propre variable avant de lancer awk. Écrivez le programme awk et les expressions sed entre guillemets simples.
  • Oubli de g dans sed. Sans lui, seule la première correspondance de la ligne est remplacée, les autres restent.
  • sed -i sans vérification. Une expression régulière erronée abîme le fichier sans prévenir. Lancez d'abord sans -i ou utilisez -i.bak.
  • + et | ne fonctionnent pas dans grep. C'est la syntaxe étendue : il faut grep -E (ou sed -E).
  • Le point dans le motif. grep 192.168.1.1 trouvera aussi 192x168y1z1 : le point signifie « n'importe quel caractère ». Utilisez grep -F ou échappez-le avec \..
  • Espaces dans les colonnes. Si un champ peut contenir des espaces (CSV, chemin), indiquez explicitement le séparateur : awk -F, ou awk -F'\t'.
  • cat inutile. cat file | grep x fonctionne, mais grep x file est plus court et ne lance pas de processus supplémentaire.

Par quoi remplacer grep, sed et awk

Pour le JSON, ces outils sont peu pratiques : mieux vaut analyser la structure avec jq (jq '.items[] | select(.status=="active") | .name'), et le YAML avec yq. Pour une recherche récursive rapide dans de grands projets, on utilise souvent ripgrep (commande rg), qui tient compte de .gitignore par défaut. Si la syntaxe de Perl vous est plus familière, perl -pe 's/a/b/g' et perl -lane 'print $F[0]' remplacent sed et awk en une ligne. Mais grep, sed et awk sont présents pratiquement sur tous les serveurs sans installation, c'est pourquoi il faut les connaître en premier.

Conclusion

grep cherche les lignes, sed les modifie, awk travaille avec les colonnes et calcule. Retenez le jeu de base : grep -rniE et -A/-B/-C, sed 's/.../.../g' avec -i.bak et -n 'Np', awk -F avec $1, $NF, les conditions et le bloc END. Avec ces briques, on construit presque toute analyse de logs. Ces exemples grep, sed et awk, ainsi que find, jq et curl, sont détaillés en pratique dans la leçon du cours Linux consacrée au traitement de texte dans le terminal.

Questions fréquentes

Quelle est la différence entre grep et egrep ?

egrep est un alias obsolète de grep -E (expressions régulières étendues). Les versions actuelles de GNU grep affichent un avertissement lors de l'appel à egrep ; utilisez donc grep -E.

Comment rechercher un texte dans tous les fichiers d'un répertoire sous Linux ?

Utilisez grep -rn "texte" /chemin : -r cherche récursivement, -n affiche le numéro de ligne. Pour limiter les types de fichiers, ajoutez --include="*.php".

Comment remplacer un texte dans de nombreux fichiers à la fois ?

Combinez la recherche et sed : grep -rl "old" . | xargs sed -i 's/old/new/g'. Avant cela, il est prudent de faire un commit ou une sauvegarde.

Comment afficher plusieurs colonnes séparées par une tabulation avec awk ?

Définissez le séparateur de sortie : awk -v OFS='\t' '{print $1, $3}' file. Sans OFS, les champs sont séparés par un espace.

Comment supprimer les espaces en fin de ligne avec sed ?

La commande sed -i 's/[[:space:]]*$//' file supprime les espaces et tabulations en fin de ligne dans toutes les lignes du fichier.

Apprenez ce sujet en vidéo

Ce sujet est traité en détail avec de la pratique dans le cours « Linux: с нуля до уверенного администрирования ».

Voir le cours