sed est l’outil qu’on utilise quand on ne veut pas ouvrir un éditeur. Vous avez 50 fichiers de configuration à mettre à jour, un mot de passe à masquer, un hostname à changer de prod à staging sur tous les fichiers d’un dossier — sed fait ça en une ligne, de façon scriptable et répétable.
C’est un outil direct LFCS (“Compare and Manipulate File Content”) et RHCSA (“Create and Edit Text Files”, “Use regular expressions to find, replace, and delete strings”).
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Substituer du texte avec la commande
s/avant/après/et ses variantes - Modifier un fichier directement sur disque avec
sed -isans perdre l’original - Cibler des lignes précises avec des adresses numériques ou des patterns regex
- Supprimer des lignes, des commentaires et des lignes vides
- Enchaîner plusieurs transformations en une seule commande avec
-e - Réorganiser des champs avec des groupes de capture
\1,\2 - Appliquer un workflow complet de migration de fichier de config
Dans quel contexte ?
Section intitulée « Dans quel contexte ? »sed est l’outil par défaut dès que vous devez transformer du texte de façon automatisable et non interactive :
- changer l’URL d’une base de données dans
db.conflors d’une migration prod → staging - masquer un mot de passe ou une clé API dans des fichiers de config avant de les versionner
- supprimer les commentaires et lignes vides d’un fichier de configuration pour le passer à un parser
- normaliser les espaces autour des
=dans des dizaines de fichiers.iniou.conf - extraire uniquement les lignes d’erreur d’un log pour alimenter un rapport
Dans un script de déploiement ou un playbook Ansible, sed -i est souvent la première solution — simple, sans dépendance, disponible sur tout système Linux.
La commande s — substituer du texte
Section intitulée « La commande s — substituer du texte »La commande s est le coeur de sed. Sa syntaxe :
s/PATTERN/REMPLACEMENT/FLAGS- PATTERN : expression régulière (BRE par défaut, ERE avec
-E) - REMPLACEMENT : le texte de remplacement
- FLAGS :
g(global),i(insensible à la casse),2(deuxième occurrence seulement)
Substitution basique — première occurrence par ligne
Section intitulée « Substitution basique — première occurrence par ligne »sed 's/prod/staging/' hosts.old192.168.1.10 web01.staging.example.com web01192.168.1.11 web02.staging.example.com web02192.168.1.20 db01.staging.example.com db0110.0.0.5 bastion.staging.example.com bastionSans flag, sed remplace seulement la première occurrence sur chaque ligne.
Flag /g — toutes les occurrences
Section intitulée « Flag /g — toutes les occurrences »echo "prod prod prod" | sed 's/prod/staging/g'staging staging stagingModifier in-place avec sed -i
Section intitulée « Modifier in-place avec sed -i »Sans -i, sed envoie le résultat sur la sortie standard — le fichier original est intact. Avec -i, la modification est écrite directement dans le fichier.
cp hosts.old hosts.stagingsed -i 's/prod/staging/g' hosts.stagingCréer un backup automatique avec -i.bak
Section intitulée « Créer un backup automatique avec -i.bak »L’extension passée après -i devient le suffixe du fichier de sauvegarde :
sed -i.bak 's/prod/staging/g' hosts.stagingls -1# hosts.staging ← fichier modifié# hosts.staging.bak ← copie de l'originalAdresses — cibler des lignes précises
Section intitulée « Adresses — cibler des lignes précises »Par défaut, sed applique la commande à toutes les lignes. Une adresse limite l’action à une sélection.
Adresses numériques
Section intitulée « Adresses numériques »# Modifier seulement la ligne 2sed '2s/example/EXAMPLE/' hosts.old
# Modifier les lignes 1 à 2sed '1,2s/example/EXAMPLE/' hosts.old
# Modifier la dernière lignesed '$s/example/EXAMPLE/' hosts.oldAdresses regex
Section intitulée « Adresses regex »# Modifier seulement les lignes qui contiennent "web"sed '/web/s/prod/staging/' hosts.old192.168.1.10 web01.staging.example.com web01192.168.1.11 web02.staging.example.com web02192.168.1.20 db01.prod.example.com db0110.0.0.5 bastion.prod.example.com bastionLes lignes db01 et bastion ne correspondent pas — elles ne sont pas modifiées.
Supprimer des lignes avec d
Section intitulée « Supprimer des lignes avec d »La commande d supprime les lignes sélectionnées de la sortie.
# Supprimer les commentaires et les lignes vides d'un fichier de configsed '/^#/d; /^$/d' db.confhost = db.internal.example.comport = 5432user=adminpassword= secret123database=productionmax_connections = 100connect_timeout= 30Les commentaires (# ...) et les lignes vides ont été supprimés. Le fichier original est intact — utilisez -i pour écrire le résultat.
Enchaîner plusieurs transformations avec -e
Section intitulée « Enchaîner plusieurs transformations avec -e »Plutôt que d’exécuter sed plusieurs fois, enchaînez avec -e :
sed -E \ -e '/^#/d' \ -e '/^$/d' \ -e 's/[[:space:]]*=[[:space:]]*/=/' \ db.confhost=db.internal.example.comport=5432user=adminpassword=secret123database=productionmax_connections=100connect_timeout=30Trois transformations appliquées en une passe :
- Suppression des commentaires
- Suppression des lignes vides
- Normalisation des espaces autour de
=
Groupes de capture et backreférences
Section intitulée « Groupes de capture et backreférences »Avec -E, les parenthèses (...) créent des groupes. \1, \2 réinjectent le contenu capturé dans le remplacement.
# Inverser IP et hostname dans hosts.oldsed -E 's/^([0-9.]+)([[:space:]]+)([a-z0-9.]+)/\3\2\1/' hosts.oldweb01.prod.example.com 192.168.1.10 web01web02.prod.example.com 192.168.1.11 web02db01.prod.example.com 192.168.1.20 db01bastion.prod.example.com 10.0.0.5 bastion([0-9.]+)→ groupe 1 capture l’IP([[:space:]]+)→ groupe 2 capture la séparation([a-z0-9.]+)→ groupe 3 capture le hostname
Dans le remplacement, \3\2\1 réinjecte hostname, espace, IP — dans le nouvel ordre.
Workflow complet — patcher un fichier de config pour une migration
Section intitulée « Workflow complet — patcher un fichier de config pour une migration »Voici le workflow réel utilisé lors d’une migration prod → staging :
# 1. Faire une copie de sécuritécp db.conf db.conf.orig
# 2. Appliquer toutes les transformations en une seule passesed -E -i.bak \ -e 's/host[[:space:]]*=[[:space:]]*.*/host=db.staging.example.com/' \ -e 's/database[[:space:]]*=[[:space:]]*.*/database=staging/' \ -e 's/[[:space:]]*=[[:space:]]*/=/' \ -e '/^#/d' \ -e '/^$/d' \ db.conf
# 3. Vérifier le résultatcat db.conf
# 4. Vérifier la différence avec l'originaldiff db.conf.orig db.confRésultat de cat db.conf :
host=db.staging.example.comport=5432user=adminpassword=secret123database=stagingmax_connections=100connect_timeout=30Résultat du diff :
1,3c1,2< # Configuration base de données< host = db.internal.example.com< port = 5432---> host=db.staging.example.com> port=54325,9c4,7< password= secret123< database=production< max_connections = 100< # timeout en secondes< connect_timeout= 30---> password=secret123> database=staging> max_connections=100> connect_timeout=30Le diff après sed -i est votre vérification obligatoire avant de livrer le fichier.
Extraire des lignes avec -n et p
Section intitulée « Extraire des lignes avec -n et p »Par défaut, sed affiche toutes les lignes (même non modifiées). L’option -n supprime cet affichage automatique. La commande p affiche explicitement la ligne.
Combinés, ils permettent un grep orienté ligne structurée :
# Afficher seulement les lignes avec code 500 dans access.logsed -n '/\" 500/p' access.log192.168.1.10 - alice [01/Apr/2026:08:17:30 +0000] "PUT /api/orders/7 HTTP/1.1" 500 0Pièges fréquents
Section intitulée « Pièges fréquents »| Piège | Symptôme | Solution |
|---|---|---|
Oublier /g | Seule la première occurrence est remplacée | Ajouter /g au flag |
sed -i sans backup | Fichier original perdu en cas d’erreur | Utiliser -i.bak systématiquement |
| Confondre BRE et ERE | +, ? non reconnus sans backslash | Ajouter -E pour ERE |
Slash / dans le pattern | Erreur de parsing | Utiliser un autre délimiteur : `s |
Point . non échappé | Matche trop large | Échapper : \. pour un point littéral |
| Modifier le fichier vendeur | Perdu à la prochaine mise à jour du paquet | Copier dans /etc/<service>/conf.d/ avant de modifier |
À retenir
Section intitulée « À retenir »s/avant/après/g: substitution globale sur chaque ligne-i.bak: modification in-place avec backup — toujours en production- Adresse numérique
2s/...ou regex/pattern/s/...pour cibler des lignes /pattern/d: supprimer les lignes qui correspondent-e: enchaîner plusieurs commandes en une passe-E: activer ERE pour+,?,{n,m}, groupes de capture(...)\1,\2: réinjecter un groupe capturé dans le remplacement-n ... p: afficher seulement les lignes sélectionnées (comme grep)- Vérifier avec
diffaprès toutsed -isur un fichier de config