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.
Il sert directement l'objectif RHCSA « Create and edit text files », et prolonge « Use grep and regular expressions to analyze text ». Le référentiel LFCS actuel ne le nomme pas, mais ses épreuves pratiques demandent sans cesse ce genre de modification de configuration.
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, sed -i est souvent la première solution : simple, sans dépendance, disponible sur tout système Linux. Dans un playbook Ansible, préférez les modules lineinfile et replace, qui ne modifient le fichier que si nécessaire et le signalent : un sed -i lancé par Ansible réécrit le fichier à chaque passage, sans dire s'il a changé quelque chose.
Les trois jeux de données du guide
Section intitulée « Les trois jeux de données du guide »Toutes les sorties de cette page ont été mesurées avec GNU sed 4.9 sur Debian 13, à partir des trois fichiers ci-dessous. Créez-les dans un répertoire de travail pour reproduire chaque commande. hosts.old imite un fichier /etc/hosts d'environnement de production, db.conf une configuration aux espacements irréguliers, et access.log un extrait de journal web.
cat > hosts.old <<'EOF'192.168.1.10 web01.prod.example.com web01192.168.1.11 web02.prod.example.com web02192.168.1.20 db01.prod.example.com db0110.0.0.5 bastion.prod.example.com bastionEOF
cat > db.conf <<'EOF'# Configuration base de donnéeshost = db.internal.example.comport = 5432user=adminpassword= secret123database=productionmax_connections = 100# timeout en secondesconnect_timeout= 30EOF
cat > access.log <<'EOF'192.168.1.10 - alice [01/Apr/2026:08:15:02 +0000] "GET /index.html HTTP/1.1" 200 104310.0.0.5 - bob [01/Apr/2026:08:16:44 +0000] "POST /login HTTP/1.1" 401 219192.168.1.10 - alice [01/Apr/2026:08:17:30 +0000] "PUT /api/orders/7 HTTP/1.1" 500 0EOFLa commande s, substituer du texte
Section intitulée « La commande s, substituer du texte »La commande s est le cœur 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 »La forme minimale remplace prod par staging dans hosts.old et envoie le résultat sur la sortie standard, sans toucher au fichier. Chaque ligne ne contient qu'un prod : la substitution les change donc toutes.
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, puis passe à la ligne suivante. Sur un fichier où le mot revient deux fois par ligne, la seconde occurrence reste intacte.
Flag /g, toutes les occurrences
Section intitulée « Flag /g, toutes les occurrences »Le flag g (global) applique la substitution à toutes les occurrences de chaque ligne. La démonstration la plus courte passe par echo, avec trois fois le même mot sur une seule ligne.
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, et le fichier original reste intact : c'est un filtre, comme grep. Avec -i (in-place), la modification est écrite directement dans le fichier. Le bon réflexe : lancer la commande sans -i, lire la sortie, puis relancer avec -i.
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 juste après -i devient le suffixe du fichier de sauvegarde. Sur GNU sed, elle se colle à l'option (-i.bak), sans espace :
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 »Une adresse numérique désigne une ligne par son numéro, une plage par deux numéros séparés d'une virgule, et la dernière ligne par $. Ce $ n'a rien à voir avec l'ancre de fin de ligne des regex : c'est sa position, avant la commande, qui lui donne ce sens.
# 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.oldLa dernière commande ne change que la ligne du bastion :
192.168.1.10 web01.prod.example.com web01192.168.1.11 web02.prod.example.com web02192.168.1.20 db01.prod.example.com db0110.0.0.5 bastion.prod.EXAMPLE.com bastionAdresses regex
Section intitulée « Adresses regex »Une adresse regex, écrite entre barres obliques, sélectionne les lignes qui contiennent le motif. C'est la forme la plus utile en administration : on cible un bloc de serveurs par son nom plutôt que par un numéro de ligne qui change au moindre ajout.
# 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 au motif web : elles sortent inchangées, avec leur prod. Sans adresse, la même substitution aurait tout modifié.
Supprimer des lignes avec d
Section intitulée « Supprimer des lignes avec d »La commande d (delete) supprime de la sortie les lignes sélectionnées par l'adresse. L'ancre ^ compte : sans elle, /#/d supprimerait aussi une ligne valide suivie d'un commentaire en fin de ligne.
# 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 (# ...) ont disparu, et une éventuelle ligne vide aurait subi le même sort. Le fichier original est intact : ajoutez -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'enchaîner sed | sed | sed, passez plusieurs expressions avec -e : elles s'appliquent dans l'ordre, en une seule passe sur le fichier. Le point-virgule à l'intérieur d'une même expression ('/^#/d; /^$/d') reste l'équivalent pour les cas courts.
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
=:[[:space:]]*désigne zéro espace ou plus, le quantificateur*étant détaillé dans l'encadré qui suit
Groupes de capture et backreférences
Section intitulée « Groupes de capture et backreférences »Avec -E, les parenthèses (...) créent des groupes de capture, numérotés de gauche à droite. Les backreférences \1, \2 réinjectent le contenu capturé dans le remplacement, ce qui permet de réordonner des champs sans passer par awk.
# 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 : un ou plusieurs chiffres ou points, donc l'IP([[:space:]]+)→ groupe 2 : un ou plusieurs espaces ou tabulations, donc la séparation([a-z0-9.]+)→ groupe 3 : un ou plusieurs caractères parmi minuscules, chiffres et points, donc le hostname
Sans le +, chaque classe ne prend qu'un seul caractère : ^[0-9.] s'arrête au 1 de 192.168.1.10, le caractère suivant n'est pas un espace, le motif ne correspond plus et sed laisse la ligne intacte, sans signaler d'erreur.
Dans le remplacement, \3\2\1 réinjecte hostname, séparation, IP, dans le nouvel ordre. La séparation capturée garde sa largeur d'origine, d'où l'alignement irrégulier de la sortie.
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 complet d'une migration de production vers staging : une copie de l'original, une seule passe de sed avec backup, puis deux vérifications. Chaque étape protège contre un type d'erreur différent.
# 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 : il montre exactement ce qui a changé, et révèle aussitôt une substitution trop large ou un motif qui n'a rien trouvé.
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, et la commande p affiche explicitement les lignes sélectionnées. Combinées, elles reproduisent un grep. Oubliez -n, et les lignes qui correspondent sortent en double : sur cet extrait de 3 lignes, la commande en affiche 4.
# 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 »Ces pièges ont un point commun : sed ne signale presque jamais d'erreur. Une substitution qui ne trouve rien, une regex écrite en ERE lancée en BRE, un point qui matche trop large : la commande réussit, et seul le résultat trahit le problème. D'où l'importance du diff final.
| 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 | unknown option to `s' | Utiliser un autre délimiteur : s|/old/path|/new/path|g |
Point . non échappé | Matche trop large | Échapper : \. pour un point littéral |
| Modifier le fichier livré par le paquet | Perdu à la prochaine mise à jour du paquet | Écrire la modification dans un fichier de surcharge (/etc/<service>/conf.d/, ou systemctl edit pour une unité systemd) |
À 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- Quantificateurs :
*zéro fois ou plus,+une fois ou plus,?facultatif,{n,m}entre n et m fois -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
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »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
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
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Traiter des données avec awk
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications