Aller au contenu
Administration Linux medium

sed : remplacer et supprimer du texte

36 min de lecture

Quand on doit modifier rapidement le contenu de plusieurs fichiers, effectuer des remplacements massifs ou supprimer certaines lignes en fonction d'un motif, sed est l'outil incontournable. Conçu pour l'édition de flux, sed permet de rechercher, remplacer, supprimer ou insérer du texte directement en ligne de commande, sans ouvrir les fichiers manuellement.

  • Remplacer du texte avec la commande s/ancien/nouveau/
  • Supprimer, insérer et modifier des lignes ciblées
  • Utiliser des adresses (numéros de ligne, motifs) pour cibler précisément
  • Éditer des fichiers en place avec -i (en sécurité)

sed fait partie des commandes de traitement de texte sous Linux. Chaque outil a sa spécialité :

CommandeSpécialitéQuand l'utiliser
sedÉditer du texte en fluxRemplacer, supprimer, insérer du texte
grepRechercher des patternsFiltrer les lignes matchant un motif
awkTraiter des données tabulairesExtraire/transformer des colonnes
trTranslitérer des caractèresRemplacer caractère par caractère
cutExtraire des colonnesDécouper par délimiteur ou position
findRechercher des fichiersTrouver des fichiers par attributs

Combinaisons fréquentes :

Fenêtre de terminal
# grep + sed : filtrer puis transformer
grep "ERROR" log.txt | sed 's/ERROR/ALERTE/g'
# sed + awk : modifier puis extraire
sed 's/;/,/g' data.csv | awk -F',' '{print $2}'
# find + sed : modifier plusieurs fichiers
find . -name "*.conf" -exec sed -i 's/old/new/g' {} +

sed excelle sur du texte non structuré, ligne par ligne. Sa limite est aussi sa définition : il ignore toute structure. Dès que la donnée est hiérarchique ou imbriquée, sed travaille à l'aveugle et produit des résultats fragiles. Le bon réflexe est de choisir l'outil qui comprend le format.

Donnée à traiterÉvitez sed, utilisezPourquoi
JSONjqjq connaît la structure ; sed casse sur l'imbrication, les espaces et l'ordre des clés
YAMLyq (mikefarah)l'indentation et les ancres sont signifiantes, invisibles pour une substitution de chaîne
HTML / XMLxmllint, xmlstarlet, pupHTML n'est pas un langage régulier : une regex ne sait pas suivre l'imbrication
Multi-ligne / logiqueawk ou perl -0777champs, variables et mémoire d'état que sed n'a pas

La règle tient en une phrase : sed pour du texte plat, un outil dédié pour de la donnée structurée. Sur un serveur minimal sans jq, un sed ponctuel sur du JSON peut dépanner, mais n'en faites jamais une brique de production.

🧠 Modèle mental — Comment fonctionne sed

sed = Lire ligne → Appliquer commandes → Afficher résultat

Modèle mental sed : Entrée (fichier/stdin) → Commande (s/ancien/nouveau/g) → Sortie (stdout ou fichier avec -i)

Points clés

  • sed lit le fichier ligne par ligne (flux, pas tout en mémoire)
  • Chaque ligne passe par les commandes dans l'ordre
  • Par défaut, sed affiche le résultat sur stdout (pas de modification du fichier)
  • La commande s/ancien/nouveau/ remplace du texte
  • Sans flag g, seule la première occurrence par ligne est remplacée
  • Avec -i, sed modifie directement le fichier (danger !)

Règles d'or

1
Tester sans -i avant d'éditer en place Prévisualiser les changements avec sed '...' fichier avant sed -i '...' fichier
2
Utiliser un délimiteur adapté au contenu Si le texte contient des /, utiliser # ou @ comme délimiteur : s#/chemin#/autre#

Vocabulaire essentiel

s/old/new/
Substitution : remplace old par new (1ère occurrence)
s/old/new/g
Substitution globale (toutes les occurrences)
d
Delete : supprime la ligne
p
Print : affiche la ligne
-i
In-place : modifie le fichier directement
-n
No-print : n'affiche rien sauf avec p
📚 Pour aller plus loin — 12 options avancées
a\texte
Append : ajoute après la ligne
i\texte
Insert : insère avant la ligne
c\texte
Change : remplace toute la ligne
/regex/
Adresse : cible les lignes matchant regex
1,10
Plage : lignes 1 à 10
/début/,/fin/
Plage entre deux patterns
-E
Extended regex (ERE) : +, ?, |, () sans escape
&
Dans s///, représente le texte matché
\1, \2
Backreferences : groupes capturés
y/abc/xyz/
Translitération (comme tr)
q
Quit : arrête le traitement
N
Next : ajoute la ligne suivante au buffer

sed lit le fichier ligne par ligne (flux), applique les transformations demandées, puis affiche le résultat. Par défaut, le fichier original n'est pas modifié.

Toute invocation de sed tient dans cette forme. Retenez surtout les guillemets simples autour de la commande : ils empêchent le shell d'interpréter $, * et \ avant que sed ne les voie. Avec des guillemets doubles, sed '$d' devient une commande vide parce que bash aura d'abord remplacé $d par une variable inexistante. Le fichier est facultatif : sans lui, sed lit l'entrée standard, ce qui en fait un maillon de pipeline naturel.

Fenêtre de terminal
sed [OPTIONS] 'COMMANDE' [FICHIER]

Ce découpage sert à diagnostiquer : quand une commande sed ne fait rien, l'erreur se situe presque toujours dans une seule de ces trois parties. La colonne Obligatoire signale le point le plus souvent oublié : la sortie par défaut est stdout, donc un sed qui « ne modifie pas le fichier » se comporte normalement, il manque simplement l'option -i.

ÉtapeQuestionExemplesObligatoire ?
EntréeD'où vient le texte ?fichier.txt, stdin (pipe)Un des deux
CommandeQuelle transformation ?s/old/new/g, d, p✓ Oui
SortieOù va le résultat ?stdout (défaut) ou fichier (-i)✗ Non (défaut : stdout)

La commande la plus utilisée est s (substitution) :

Fenêtre de terminal
sed 's/ancien/nouveau/' fichier.txt
ÉlémentSignification
sCommande de substitution
/Délimiteur (peut être #, @, |)
ancienTexte ou regex à rechercher
nouveauTexte de remplacement

Par défaut, seule la première occurrence par ligne est remplacée. Pour remplacer toutes les occurrences, ajoutez le flag g :

Fenêtre de terminal
sed 's/foo/bar/g' fichier.txt

Au-delà de la substitution, sed dispose d'une poignée de commandes d'une seule lettre. Deux d'entre elles se comportent différemment des autres : p duplique la ligne au lieu de l'afficher seule, parce que sed imprime déjà chaque ligne par défaut ; on l'accompagne donc systématiquement de l'option -n. Et q interrompt la lecture du fichier, ce qui en fait la commande la plus efficace pour extraire les premières lignes d'un fichier de plusieurs gigaoctets.

CommandeEffetExemple
dSupprime la ligne/debug/d
pAffiche la ligne-n '/error/p'
i\texteInsère avant la ligne1i\# En-tête
a\texteAjoute après la ligne$a\# Fin
c\texteRemplace la ligne entière3c\Nouvelle ligne
qQuitte après cette ligne10q

Par défaut, sed applique la commande à toutes les lignes. On peut cibler avec des adresses :

AdresseCe qu'elle cibleExemple
5Ligne numéro 5sed '5d' f.txt
$Dernière lignesed '$d' f.txt
/pattern/Lignes contenant "pattern"sed '/error/d' f.txt
1,10Lignes 1 à 10sed '1,10d' f.txt
/début/,/fin/Plage entre deux patternssed '/BEGIN/,/END/d' f.txt

Les flags se placent après le dernier délimiteur et se cumulent (gi remplace partout sans tenir compte de la casse). Le flag numérique est le moins connu et le plus utile sur des logs : s/a/X/2 ne touche que la deuxième occurrence de chaque ligne. Il se combine d'ailleurs avec g sous la forme s/a/X/2g, qui remplace à partir de la deuxième occurrence jusqu'à la fin de la ligne. Attention au flag i : c'est une extension GNU, absente de POSIX.

FlagEffetExemple
gGlobal (toutes occurrences)s/a/b/g
iInsensible à la casses/error/warning/gi
pAffiche si substitution faite-n 's/a/b/p'
2Remplace la 2ème occurrences/a/b/2

Quand le texte contient des /, utilisez un autre délimiteur. Le caractère placé juste après le s devient le délimiteur, quel qu'il soit : sed ne réserve rien au slash. Comparez les deux formes ci-dessous, elles font strictement la même chose ; seule la seconde reste relisible dans six mois.

Fenêtre de terminal
# ✗ Illisible et source d'erreurs
sed 's/\/var\/log/\/opt\/logs/g' fichier.txt
# ✓ Beaucoup plus clair avec #
sed 's#/var/log#/opt/logs#g' fichier.txt

Par défaut, sed affiche le résultat sur stdout sans modifier le fichier. Pour modifier directement :

Fenêtre de terminal
# Modifie le fichier (DANGER si erreur)
sed -i 's/old/new/g' fichier.txt
# ✓ Crée un backup avant modification
sed -i.bak 's/old/new/g' fichier.txt

Règle d'or : toujours tester sans -i d'abord !

Fenêtre de terminal
# 1. Tester
sed 's/old/new/g' fichier.txt
# 2. Vérifier le résultat, puis seulement :
sed -i.bak 's/old/new/g' fichier.txt

Ces quatre erreurs représentent la majorité des tickets « mon sed ne marche pas ». Toutes se diagnostiquent de la même façon : relancer la commande sans -i et regarder la sortie. Le cas le plus trompeur est le dernier, « rien ne se passe » : sed ne signale jamais l'absence de correspondance et renvoie un code de retour 0, donc un script qui ne vérifie pas son résultat continue comme si la modification avait eu lieu.

ErreurCauseSolution
Seule la 1ère occurrence est remplacéeOubli du flag gAjouter g : s/old/new/g
Erreur de syntaxe avec des chemins/ dans le texteUtiliser # comme délimiteur
Fichier modifié par erreur-i sans test préalableToujours tester sans -i d'abord
Rien ne se passePas de match (casse ?)Vérifier avec grep ou utiliser i (insensible)

Maintenant que vous comprenez la logique de sed, voici seize modèles prêts à l'emploi. Chacun donne sa formule générale et un exemple concret.

Remplacer la première occurrence d'un texte sur chaque ligne. C'est la forme de base, et aussi le piège le plus courant : sans le flag g, les occurrences suivantes de la même ligne restent intactes.

Fenêtre de terminal
sed 's/ancien/nouveau/' <fichier> # formule
sed 's/erreur/warning/' log.txt # exemple
  • ancien : texte ou regex à rechercher
  • nouveau : texte de remplacement

Remplacer toutes les occurrences sur chaque ligne. Le flag g agit à l'intérieur d'une ligne, pas sur l'ensemble du fichier : sed traite déjà toutes les lignes par défaut.

Fenêtre de terminal
sed 's/ancien/nouveau/g' <fichier> # formule
sed 's/foo/bar/g' fichier.txt # exemple
  • g : flag global, toutes les occurrences de la ligne

Remplacer un texte quelle que soit la casse. Ce flag est une extension GNU absente de POSIX, donc à éviter dans un script destiné à tourner sur macOS ou sur un système embarqué.

Fenêtre de terminal
sed 's/ancien/nouveau/gi' <fichier> # formule
sed 's/error/warning/gi' log.txt # exemple
  • i : flag insensible à la casse (GNU sed)

Éviter les échappements quand le texte contient des /. Choisissez un caractère absent du motif comme du remplacement, sinon vous déplacez le problème au lieu de le résoudre.

Fenêtre de terminal
sed 's#ancien#nouveau#g' <fichier> # formule
sed 's#/var/log#/opt/logs#g' paths.txt # exemple
  • # : délimiteur alternatif (#, @, etc.) à la place de /

Supprimer les lignes contenant un motif. La suppression porte sur la ligne entière dès qu'une correspondance est trouvée n'importe où dedans, pas seulement en début de ligne.

Fenêtre de terminal
sed '/motif/d' <fichier> # formule
sed '/DEBUG/d' log.txt # exemple
  • motif : pattern regex à reconnaître
  • d : commande delete

Nettoyer un fichier en retirant les lignes vides. Attention, ^$ ne reconnaît que les lignes strictement vides : une ligne contenant un espace ou une tabulation survit, il faut alors /^[[:space:]]*$/d.

Fenêtre de terminal
sed '/^$/d' <fichier> # formule
sed '/^$/d' texte.txt # exemple
  • ^$ : regex d'une ligne vide (début = fin)

Appliquer une commande uniquement sur une ligne précise. Le numéro se compte sur l'ensemble des fichiers passés en argument, pas par fichier : avec plusieurs fichiers, la ligne 5 n'existe qu'une fois.

Fenêtre de terminal
sed 'N<commande>' <fichier> # formule
sed '5d' fichier.txt # exemple : supprime la ligne 5
  • N : numéro de ligne ciblé

Appliquer une commande sur un ensemble de lignes. Les deux bornes sont incluses, et $ peut remplacer la borne haute pour aller jusqu'à la fin du fichier (2,$d).

Fenêtre de terminal
sed 'N,M<commande>' <fichier> # formule
sed '2,5d' fichier.txt # exemple : supprime les lignes 2 à 5
  • N,M : de la ligne N à la ligne M incluses

Cibler les lignes situées entre deux patterns. Les deux lignes délimitantes sont incluses dans la plage. Si le motif de fin n'apparaît jamais, la plage court jusqu'à la fin du fichier.

Fenêtre de terminal
sed '/début/,/fin/<commande>' <fichier> # formule
sed '/BEGIN/,/END/d' fichier.txt # exemple
  • /début/,/fin/ : plage délimitée par deux motifs

Modifier directement le fichier. Aucune confirmation n'est demandée et aucun retour en arrière n'est possible : exécutez toujours la commande sans -i d'abord pour vérifier la sortie.

Fenêtre de terminal
sed -i '<commande>' <fichier> # formule
sed -i 's/old/new/g' config.conf # exemple
  • -i : in-place, modifie le fichier. Toujours tester sans -i d'abord.

Modifier un fichier en conservant une copie de secours. Le suffixe est collé à l'option, sans espace : -i.bak fonctionne, -i .bak échoue en traitant .bak comme un nom de fichier.

Fenêtre de terminal
sed -i.bak '<commande>' <fichier> # formule
sed -i.bak 's/old/new/g' config.conf # exemple
  • -i.bak : crée fichier.bak avant de modifier

Ajouter du texte avant une ligne. La forme condensée sur une seule ligne est une extension GNU ; la version POSIX impose un retour à la ligne après l'antislash.

Fenêtre de terminal
sed '<adresse>i\<texte>' <fichier> # formule
sed '1i\# En-tête ajouté' fichier.txt # exemple
  • i\ : commande insert, ajoute avant la ligne ciblée

Ajouter du texte après une ligne. Combinée à l'adresse $, elle ajoute une ligne en fin de fichier, geste utile pour compléter une configuration sans l'ouvrir dans un éditeur.

Fenêtre de terminal
sed '<adresse>a\<texte>' <fichier> # formule
sed '/END/a\# Commentaire' fichier.txt # exemple
  • a\ : commande append, ajoute après la ligne ciblée

Extraire les lignes d'un motif, comme grep. L'option -n est indissociable de p : sans elle, sed affiche déjà chaque ligne et les lignes reconnues apparaissent en double.

Fenêtre de terminal
sed -n '/motif/p' <fichier> # formule
sed -n '/ERROR/p' log.txt # exemple
  • -n : désactive l'affichage automatique
  • p : commande print, affiche la ligne

Réutiliser une partie capturée dans le remplacement. En regex basique, les parenthèses de groupe s'échappent (\( et \)) ; avec l'option -E, elles s'écrivent sans antislash.

Fenêtre de terminal
sed 's/\(motif\)/\1 ajout/' <fichier> # formule
sed 's/\([0-9]*\)/ID:\1/' fichier.txt # exemple
  • \(\) : groupe de capture
  • \1 : référence au premier groupe capturé

Insérer le texte reconnu dans le remplacement. Pour insérer un & littéral, échappez-le en \&, sinon sed recopie le texte reconnu à la place.

Fenêtre de terminal
sed 's/motif/[&]/g' <fichier> # formule
sed 's/[0-9]\+/(&)/g' fichier.txt # exemple
  • & : représente l'intégralité du texte reconnu

Sept erreurs reviennent constamment avec sed. Pour chacune : la commande piégée, le symptôme, la cause et la correction.

Fenêtre de terminal
sed 's/foo/bar/' fichier.txt # ✗ ne remplace que la 1ʳᵉ occurrence par ligne

Symptôme : certaines occurrences ne sont pas remplacées. Cause : sans g, sed ne touche que la première occurrence de chaque ligne.

Fenêtre de terminal
sed 's/foo/bar/g' fichier.txt # ✓ flag global
Fenêtre de terminal
sed 's//var/log//opt/logs/' fichier.txt # ✗ erreur de syntaxe

Symptôme : erreur unknown command ou résultat inattendu. Cause : les / du texte sont pris pour des délimiteurs.

Fenêtre de terminal
sed 's#/var/log#/opt/logs#g' fichier.txt # ✓ délimiteur alternatif
Fenêtre de terminal
sed -i 's/important/supprimé/g' fichier.conf # ✗ exécuté sans test

Symptôme : données perdues, fichier corrompu. Cause : -i modifie le fichier sans retour arrière possible.

Fenêtre de terminal
sed 's/old/new/g' fichier # ✓ tester d'abord, puis sed -i.bak
Fenêtre de terminal
sed 's/fichier.txt/fichier.log/' fichier # ✗ le . matche n'importe quel caractère

Symptôme : des correspondances inattendues (fichierXtxt est aussi reconnu). Cause : le point . est un métacaractère regex.

Fenêtre de terminal
sed 's/fichier\.txt/fichier.log/g' fichier # ✓ point échappé
Fenêtre de terminal
sed -i 's/old/new/' fichier # ✗ échoue sur macOS (BSD sed)

Symptôme : erreur invalid command code sur macOS. Cause : BSD sed exige une extension après -i, même vide.

Fenêtre de terminal
sed -i '' 's/old/new/' fichier # ✓ sur macOS, ou installer GNU sed
Fenêtre de terminal
sed 's/$/\n/' fichier # ✗ marche avec GNU sed, pas garanti ailleurs

Symptôme : la commande produit bien une ligne vide après chaque ligne sur un serveur Linux, puis un n littéral apparaît sur le poste macOS d'un collègue. Cause : POSIX ne définit pas le sens de \n dans la partie remplacement. GNU sed l'interprète comme un vrai saut de ligne, les implémentations BSD ne le garantissent pas. Pour un script qui doit tourner partout, on injecte le saut de ligne depuis le shell.

Fenêtre de terminal
sed 's/$/\'$'\n''/' fichier # ✓ portable : le saut de ligne vient de bash ($'\n')
Fenêtre de terminal
sed 's/<.*>//g' fichier # ✗ supprime du premier < au dernier >

Symptôme : <a>texte<b> devient vide au lieu de texte. Cause : .* est gourmand, il reconnaît le maximum possible.

Fenêtre de terminal
sed 's/<[^>]*>//g' fichier # ✓ classe négative : s'arrête au premier >
Fenêtre de terminal
sed -i 's/old/new/' /etc/service/config # ✗ si config est un symlink, le lien saute

Symptôme : le lien symbolique disparaît, remplacé par un fichier classique, et la cible d'origine reste inchangée. Cause : -i écrit un fichier temporaire puis le renomme sur le chemin, ce qui détruit le lien.

Fenêtre de terminal
sed -i --follow-symlinks 's/old/new/' /etc/service/config # ✓ GNU : suit le lien
Fenêtre de terminal
sed 's/\d/X/g' fichier # ✗ \d ne signifie PAS « chiffre » dans sed

Symptôme : des lettres sont remplacées au lieu des chiffres (\d reconnaît la lettre d). Cause : contrairement aux regex PCRE, sed ne connaît pas \d. Solution : la classe POSIX, portable.

Fenêtre de terminal
sed 's/[[:digit:]]/X/g' fichier # ✓ ou [0-9]
Fenêtre de terminal
sed 's/local$/remote/' config.txt # ✗ échoue si le fichier est en CRLF

Symptôme : aucun remplacement alors que le motif paraît correct. Cause : un \r invisible reste en fin de ligne, donc l'ancre $ matche avant lui. Solution : retirer le \r d'abord.

Fenêtre de terminal
sed 's/\r$//' config.txt # ✓ normalise en LF (GNU)

Rien ne remplace la pratique. Créez l'environnement de test ci-dessous, puis déroulez les huit étapes. À la fin, nettoyez avec rm -rf ~/sed-lab.

Ce script crée cinq fichiers de test dans ~/sed-lab : une configuration, un log, un CSV, une liste de chemins et un fichier « brouillon » à nettoyer.

Fenêtre de terminal
# Créer le lab
mkdir -p ~/sed-lab
cd ~/sed-lab
# Fichier de configuration type
cat > config.conf << 'EOF'
# Configuration serveur
server_host=localhost
server_port=8080
debug_mode=true
log_level=INFO
database_url=postgres://localhost:5432/mydb
max_connections=100
EOF
# Fichier de logs
cat > access.log << 'EOF'
192.168.1.10 - - [15/Jan/2025:10:30:00] "GET /index.html HTTP/1.1" 200 1234
192.168.1.20 - - [15/Jan/2025:10:30:05] "POST /api/users HTTP/1.1" 201 567
192.168.1.10 - - [15/Jan/2025:10:30:10] "GET /style.css HTTP/1.1" 200 890
192.168.1.30 - - [15/Jan/2025:10:30:15] "GET /error HTTP/1.1" 404 123
192.168.1.10 - - [15/Jan/2025:10:30:20] "DELETE /api/users/5 HTTP/1.1" 403 45
EOF
# Fichier CSV
cat > users.csv << 'EOF'
id,nom,email,role
1,Alice,alice@example.com,admin
2,Bob,bob@example.com,user
3,Charlie,charlie@example.com,user
4,Diana,diana@example.com,moderator
EOF
# Fichier avec chemins
cat > paths.txt << 'EOF'
/var/log/syslog
/home/user/documents/report.pdf
/etc/nginx/nginx.conf
/usr/local/bin/script.sh
EOF
# Fichier à nettoyer
cat > messy.txt << 'EOF'
Ligne avec espaces au début
Ligne normale
Autre ligne avec espaces
Ligne vide après
Encore du texte
Espaces partout
EOF
echo "✓ Lab créé dans ~/sed-lab"
ls -la ~/sed-lab

Ces huit commandes s'exécutent sans -i sauf la septième : elles affichent le résultat à l'écran et laissent les fichiers du lab intacts. Prenez l'habitude de comparer la sortie au fichier d'origine avec diff <(sed ...) fichier avant de passer à l'étape suivante. La progression va du remplacement simple vers le ciblage par adresse, qui est la vraie compétence à acquérir : savoir restreindre une transformation à quelques lignes évite les dégâts sur les fichiers de configuration.

  1. Substitution simple. Remplacez localhost par 127.0.0.1 dans config.conf.

    Fenêtre de terminal
    sed 's/localhost/127.0.0.1/' ~/sed-lab/config.conf

    s/ancien/nouveau/ remplace la première occurrence sur chaque ligne. Pour toutes les occurrences : ajoutez le flag g.

  2. Délimiteur alternatif. Remplacez /var/log par /opt/logs dans paths.txt.

    Fenêtre de terminal
    sed 's#/var/log#/opt/logs#' ~/sed-lab/paths.txt

    Quand le texte contient des /, on utilise un autre délimiteur (# ici).

  3. Supprimer des lignes. Supprimez les lignes contenant 404 dans access.log.

    Fenêtre de terminal
    sed '/404/d' ~/sed-lab/access.log

    /motif/d supprime les lignes qui contiennent le motif.

  4. Supprimer les lignes vides. Retirez les lignes vides de messy.txt.

    Fenêtre de terminal
    sed '/^$/d' ~/sed-lab/messy.txt

    ^$ reconnaît une ligne vide (début immédiatement suivi de la fin).

  5. Cibler une ligne par numéro. Remplacez user par admin uniquement sur la ligne 3 de users.csv.

    Fenêtre de terminal
    sed '3s/user/admin/' ~/sed-lab/users.csv

    Le numéro placé avant la commande la restreint à cette ligne.

  6. Plage de lignes. Remplacez @example.com par @company.org sur les lignes 2 à 4 de users.csv.

    Fenêtre de terminal
    sed '2,4s/@example.com/@company.org/' ~/sed-lab/users.csv

    N,M cible les lignes de N à M incluses.

  7. Édition en place avec sauvegarde. Modifiez config.conf en remplaçant true par false, en gardant une sauvegarde.

    Fenêtre de terminal
    sed -i.bak 's/true/false/' ~/sed-lab/config.conf

    -i.bak modifie le fichier et crée config.conf.bak au préalable.

  8. Supprimer les espaces en début de ligne. Retirez les espaces au début de chaque ligne de messy.txt.

    Fenêtre de terminal
    sed 's/^[[:space:]]*//' ~/sed-lab/messy.txt

    ^[[:space:]]* reconnaît zéro espace ou plus en début de ligne.

Huit exercices pour valider votre maîtrise. Tous se traitent sur les fichiers du lab ~/sed-lab. Cherchez d'abord par vous-même, puis dépliez la solution pour vous corriger.

Ces trois premiers exercices ne mobilisent qu'une commande à la fois : substituer, changer de délimiteur, supprimer des lignes. Écrivez votre réponse avant d'ouvrir la solution, puis exécutez-la sur le lab : une commande qui semble juste sur le papier échoue souvent sur un détail de délimiteur ou d'échappement.

Exercice 1, Substitution basique. Remplacez tous les error par warning dans access.log. Indice : n'oubliez pas le flag g.

Voir la solution
Fenêtre de terminal
sed 's/error/warning/g' ~/sed-lab/access.log

Le flag g remplace toutes les occurrences, pas seulement la première de chaque ligne.

Exercice 2, Remplacer des chemins. Remplacez /usr/local par /opt dans paths.txt. Indice : les / du texte gênent le délimiteur par défaut.

Voir la solution
Fenêtre de terminal
sed 's#/usr/local#/opt#g' ~/sed-lab/paths.txt

On utilise # comme délimiteur pour éviter d'échapper les /.

Exercice 3, Supprimer les commentaires. Supprimez toutes les lignes commençant par # dans config.conf. Indice : ^ représente le début de ligne, d supprime.

Voir la solution
Fenêtre de terminal
sed '/^#/d' ~/sed-lab/config.conf

/^#/ reconnaît les lignes commençant par # ; d les supprime.

Les trois exercices suivants combinent une regex et une adresse. C'est le passage difficile : il faut décrire une position (fin de ligne, numéro de ligne) et non plus seulement un mot. Si votre commande ne renvoie rien, vérifiez d'abord le motif seul avec grep avant d'incriminer sed.

Exercice 4, Nettoyer les espaces. Supprimez les espaces en fin de ligne de messy.txt. Indice : [[:space:]] reconnaît les espaces, $ la fin de ligne.

Voir la solution
Fenêtre de terminal
sed 's/[[:space:]]*$//' ~/sed-lab/messy.txt

[[:space:]]*$ reconnaît zéro espace ou plus juste avant la fin de ligne.

Exercice 5, Modifier une ligne précise. Changez le contenu entier de la ligne 3 de users.csv en MODIFIÉ. Indice : c\ remplace toute une ligne.

Voir la solution
Fenêtre de terminal
sed '3c\MODIFIÉ' ~/sed-lab/users.csv

3c\ cible la ligne 3 ; c\ remplace son contenu entier.

Exercice 6, Extraire des lignes (comme grep). Affichez uniquement les lignes d'access.log contenant 404. Indice : -n désactive l'affichage auto, p affiche les lignes reconnues.

Voir la solution
Fenêtre de terminal
sed -n '/404/p' ~/sed-lab/access.log

-n coupe l'affichage par défaut ; /404/p n'affiche que les lignes correspondantes.

Les deux derniers exercices touchent aux gestes qu'on retrouve dans les scripts de production : préfixer un flux et modifier un fichier en place. Le second est le seul de la série qui écrit sur le disque ; vérifiez la présence du fichier .bak après exécution, c'est la preuve que le filet de sécurité a bien fonctionné.

Exercice 7, Ajouter un préfixe à chaque ligne. Ajoutez LOG: au début de chaque ligne d'access.log. Indice : ^ reconnaît le début de ligne.

Voir la solution
Fenêtre de terminal
sed 's/^/LOG: /' ~/sed-lab/access.log

s/^/LOG: / remplace le « début de ligne » par LOG: , donc préfixe chaque ligne.

Exercice 8, Édition en place sécurisée. Remplacez localhost par 127.0.0.1 dans config.conf en conservant une sauvegarde. Indice : -i.bak crée la sauvegarde automatiquement.

Voir la solution
Fenêtre de terminal
sed -i.bak 's/localhost/127.0.0.1/g' ~/sed-lab/config.conf

-i.bak modifie le fichier en place et crée config.conf.bak comme filet de sécurité.

Quand une substitution sed ne fonctionne pas, le problème vient le plus souvent du motif ou des délimiteurs. Voici comment diagnostiquer.

Ces quatre commandes se lancent dans l'ordre : elles isolent progressivement l'origine du problème. La troisième, sed -n '/pattern/=', affiche les numéros de ligne reconnus et répond à la seule question qui compte au départ : le motif reconnaît-il quelque chose ? Si elle ne renvoie rien, le problème est dans la regex, pas dans la substitution. Si elle renvoie des numéros mais que le remplacement n'apparaît pas, l'erreur est dans la partie droite du s///.

Fenêtre de terminal
# Toujours prévisualiser avant d'utiliser -i
sed 's/old/new/g' fichier
# Voir quelles lignes sont reconnues par un motif
sed -n '/pattern/p' fichier
# Afficher les numéros des lignes reconnues
sed -n '/pattern/=' fichier
# Valider le motif isolément avec grep
grep 'pattern' fichier

Contrairement à l'absence de correspondance, ces quatre situations produisent un message d'erreur explicite et un code de retour non nul, donc un script avec set -e s'arrête dessus. Lisez le message en entier : sed indique le numéro de caractère fautif dans l'expression, ce qui localise immédiatement le délimiteur manquant.

Message d'erreurCause probableSolution
unterminated 's' commandDélimiteur de fermeture manquant, ou / non échappé dans le texteS'assurer d'avoir exactement 3 délimiteurs : s/ancien/nouveau/
unknown option -- EOption non supportée (BSD sed contre GNU sed)Vérifier sed --version ; sur macOS, installer GNU sed
no input filesAucun fichier fourni et aucune entrée standardPasser un fichier en argument, ou utiliser un pipe
invalid command codeCommande sed inconnue, ou problème de guillemetsVérifier la lettre de commande et les guillemets simples

sed est partout dans l'automatisation, mais quelques réflexes évitent des incidents en CI et en gestion de configuration.

sed -i 's/a/b/' fichier fonctionne sur Linux (GNU sed) mais échoue sur macOS (BSD sed), où -i attend un suffixe de sauvegarde juste après. Un pipeline qui tourne à la fois sur des runners Linux et macOS doit utiliser une forme portable :

Fenêtre de terminal
sed -i.bak 's/a/b/' fichier && rm fichier.bak # portable GNU + BSD
# ou, encore plus robuste :
perl -pi -e 's/a/b/' fichier

En gestion de configuration, un sed -i lancé via le module shell est rejoué à chaque exécution et rapporte toujours changed : Ansible ne peut pas savoir si la modification est déjà appliquée, et un ajout de ligne finit par se dupliquer. Pour éditer un fichier de configuration durablement, les modules lineinfile et replace sont déclaratifs et idempotents, gèrent --check/--diff et créent une sauvegarde. Gardez sed pour les transformations ponctuelles, pas pour l'état d'un serveur.

Dans un Dockerfile, un RUN sed -i fige la modification dans une couche d'image. Préférez configurer au runtime (ENV, variables, script d'entrée) pour qu'une seule image serve tous les environnements. Pour injecter des variables dans un fichier (${VAR}), envsubst est plus sûr que sed (ni problème de délimiteur, ni risque d'injection) ; dès qu'il faut des conditions ou des boucles, passez à un vrai moteur de templates comme Jinja2.

Les cinq tableaux qui suivent regroupent ce qui sert au quotidien, classé par nature : options, adresses, commandes, regex, délimiteurs. Les entrées marquées GNU n'existent pas sur macOS ni sur les BusyBox embarquées, à vérifier avant de les glisser dans un script partagé.

Les options se placent avant la commande. Retenez le couple -n et p : c'est la combinaison qui transforme sed en outil d'extraction. L'option -E mérite aussi votre attention, car elle bascule vers les regex étendues et supprime les échappements pénibles : \(...\) devient (...), et \+ devient +.

ÉlémentRôleExemple
sed 'cmd' fichierApplique une commande au fichiersed 's/a/b/' f.txt
sed -e 'cmd1' -e 'cmd2'Enchaîne plusieurs commandessed -e 's/a/b/' -e 's/c/d/'
cmd | sed 'cmd'Traite l'entrée d'un pipecat f.txt | sed 's/a/b/'
-iÉdition en place (modifie le fichier)sed -i 's/a/b/' f.txt
-i.bakÉdition en place avec sauvegardesed -i.bak 's/a/b/' f.txt
-nMode silencieux (rien par défaut)sed -n '/err/p' f.txt
-E (ou -r)Active les regex étendues (ERE)sed -E 's/[0-9]+/X/g'
-f script.sedLit les commandes depuis un fichiersed -f cmds.sed fichier

L'adresse se place devant la commande et restreint son champ d'action. Une seule entrée du tableau est une extension GNU absente de POSIX : 1~2, qui sélectionne une ligne sur deux. La négation ! est en revanche standard, et c'est la plus utile en pratique : /DEBUG/!d conserve uniquement les lignes de débogage, ce qui évite d'écrire la regex inverse, souvent impossible à formuler proprement.

AdresseRôleExemple
5Ligne numéro 55s/a/b/
$Dernière ligne$d
/regex/Lignes reconnues par la regex/error/d
1,10Lignes 1 à 101,10s/a/b/
/début/,/fin/Plage entre deux motifs/BEGIN/,/END/d
1~2Ligne 1 puis une sur deux (GNU)1~2d
!Inverse l'adresse (NON)/DEBUG/!d

Les trois commandes d'insertion i\, a\ et c\ sont celles qui posent le plus de problèmes de portabilité : GNU accepte le texte sur la même ligne (1i\# Header), alors que la forme POSIX stricte impose un retour à la ligne après l'antislash. Si un script d'insertion échoue sur un autre système, c'est presque toujours de là que vient le problème.

CommandeRôleExemple
s/old/new/Substitue (1ʳᵉ occurrence)s/error/warning/
s/old/new/gSubstitue (toutes les occurrences)s/foo/bar/g
s/old/new/giSubstitue sans tenir compte de la casses/error/warning/gi
dSupprime la ligne/^#/d
pAffiche la ligne-n '/error/p'
qQuitte après cette ligne10q
=Affiche le numéro de ligne/error/=
i\texteInsère une ligne avant1i\# Header
a\texteAjoute une ligne après$a\# Footer
c\texteRemplace la ligne entière3c\Nouvelle ligne

sed utilise par défaut les regex basiques (BRE), pas la syntaxe PCRE des langages de programmation. Concrètement, les parenthèses de groupe s'écrivent \(...\) et non (...). GNU accepte bien \w et \s, mais ce sont des extensions non portables, et \d n'y signifie pas « chiffre » : préférez les classes POSIX [[:digit:]], [[:alnum:]] et [[:space:]], qui fonctionnent sur toutes les implémentations. L'option -E bascule en regex étendues et rétablit les parenthèses sans antislash.

ÉlémentRôleExemple
&Le texte reconnu, dans le remplacements/[0-9]*/(&)/
\1, \2Groupes capturéss/\(.*\)/[\1]/
\(\)Groupe de capture (regex basique)s/\(mot\)/[\1]/
^ / $Début / fin de lignes/^/PREFIX: /
.N'importe quel caractères/a.c/X/
[abc] / [^abc]Classe / négation de classes/[^0-9]//g

Le caractère qui suit immédiatement le s devient le délimiteur : sed n'impose pas le /, c'est une simple convention. Choisissez un caractère absent du motif et du remplacement, sinon vous revenez au problème de départ. Le # convient aux chemins de fichiers, le @ ou le , aux URL contenant des //. Un délimiteur bien choisi supprime tous les antislashs et rend la commande relisible six mois plus tard.

FormeRôleExemple
s#old#new#Délimiteur # (idéal pour les chemins)s#/var#/opt#g
s@old@new@Délimiteur @s@http://@https://@g
s|old|new|Délimiteur |s|foo|bar|g

Vous maîtrisez sed lorsque vous pouvez cocher chacun de ces points :

  • Je sais utiliser s/ancien/nouveau/ pour substituer
  • Je sais utiliser le flag g pour remplacer globalement
  • Je sais utiliser un délimiteur alternatif (#, @)
  • Je sais supprimer des lignes avec d
  • Je sais cibler des lignes par numéro ou par motif
  • Je sais utiliser -n et p pour extraire des lignes
  • Je sais éditer en place avec -i et -i.bak
  • Je sais insérer ou ajouter une ligne avec i\ et a\
  • Je sais utiliser les références arrière (\1, &)
  • Je sais diagnostiquer une substitution qui ne fonctionne pas

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

  • sed édite du texte plat ligne par ligne : substitution s///, suppression d, adresses pour cibler.
  • Le flag g remplace toutes les occurrences d'une ligne ; sans lui, seulement la première.
  • Toujours prévisualiser sans -i, puis -i.bak pour garder un filet de sécurité.
  • Pour de la donnée structurée, changez d'outil : jq (JSON), yq (YAML), awk ou perl (multi-ligne).
  • En CI, méfiez-vous du GNU contre BSD (-i) ; en gestion de configuration, préférez Ansible lineinfile (idempotent).
  • Pièges classiques : symlink cassé par -i, faux-ami \d, fins de ligne CRLF.

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