Linux / Commande sed : remplacer du texte et vérifier une modification
sed est un éditeur de flux qui lit du texte, applique des règles d'édition et affiche le résultat. Par défaut, il ne change pas le fichier d'entrée. La commande s/motif/remplacement/ remplace la première correspondance de chaque ligne ; le suffixe g remplace toutes les correspondances de la ligne.
Sed convient aux transformations répétitives, à la sélection de lignes et à leur suppression dans la sortie. Pour modifier un fichier directement avec -i, vérifiez d'abord le résultat et préparez une sauvegarde. Les exemples suivants visent GNU sed dans Bash ; la syntaxe d'édition sur place des autres implémentations doit être vérifiée dans leur propre manuel.
Préparer le fichier et comprendre le traitement par ligne
sed [options] 'script' [fichiers…]
Sans fichier, sed lit l'entrée standard. Dans le traitement ordinaire illustré ici, il lit une ligne, exécute les règles et l'affiche automatiquement. Les scripts plus avancés peuvent modifier ce cycle ; il n'est pas nécessaire de les utiliser pour ces premières transformations.
Créez un répertoire d'exercice neuf avec un fichier de deux lignes :
sed_lab=$(mktemp -d "$HOME/sed-lab.XXXXXX")
cd -- "$sed_lab"
printf 'red car\nred red\n' > config.txt
Le premier red n'apparaît qu'une fois sur la première ligne, mais deux fois sur la seconde. Le répertoire ne contient que les données fictives de l'exercice ; notez son chemin pour retrouver les copies et quittez-le ensuite avec cd "$HOME". Consultez man sed pour les options installées.
Comparer première correspondance et remplacement global
sed 's/red/green/' config.txt > first.txt
sed 's/red/green/g' config.txt > all.txt
cat config.txt first.txt all.txt
L'affichage successif des trois fichiers donne :
red car
red red
green car
green red
green car
green green
Les deux premières lignes sont l'original, qui est resté intact. Les deux suivantes montrent une substitution par ligne. Les deux dernières montrent toutes les substitutions avec g. « Première correspondance » ne signifie donc pas « une seule occurrence dans tout le fichier ».
Le caractère / délimite le motif et le remplacement. Si ces textes contiennent beaucoup de barres obliques, un autre séparateur peut rendre l'expression plus lisible :
printf '/old/path\n' | sed 's|/old/path|/new/path|'
La sortie est /new/path. Le changement de séparateur ne transforme pas le motif en texte littéral : ses autres caractères spéciaux conservent leur signification.
Sélectionner ou retirer des lignes dans la sortie
-n désactive l'affichage automatique ; la commande p affiche alors explicitement les lignes choisies. Pour ne garder que la deuxième ligne :
sed -n '2p' config.txt
Le résultat est red red. Sans -n, une commande 2p ajouterait un affichage explicite à l'affichage automatique, ce qui ferait apparaître cette ligne deux fois.
Pour retirer la première ligne du résultat, utilisez d :
sed '1d' config.txt
La sortie est encore red red. Le fichier conserve pourtant ses deux lignes : cette suppression porte ici sur le flux affiché, puisque -i n'est pas utilisé.
Plusieurs règles peuvent se suivre avec -e. Elles s'appliquent dans l'ordre, et une règle ultérieure voit les transformations déjà effectuées :
sed -e 's/red/green/g' -e 's/car/bike/' config.txt
green bike
green green
Distinguer une expression régulière du texte littéral
Le motif de recherche est une expression régulière. Le point représente généralement un caractère quelconque, au lieu du point littéral :
printf 'a.b axb\n' | sed 's/a.b/X/g'
printf 'a.b axb\n' | sed 's/a\.b/X/g'
La première commande donne X X, la seconde X axb. La barre oblique inverse protège ici le point pour l'expression régulière. Les guillemets simples protègent le script contre les développements du shell ; ils n'enlèvent pas la signification spéciale des caractères pour sed.
Le remplacement possède lui aussi ses conventions. Un & non protégé représente tout le texte correspondant :
printf 'red\n' | sed 's/red/[&]/'
printf 'red\n' | sed 's/red/\&/'
Vous obtenez respectivement [red] et un & littéral. Ne construisez pas un script de remplacement à partir d'une valeur arbitraire sans prendre en compte les caractères spéciaux du motif, du remplacement et du shell.
L'option -E active les expressions régulières étendues. Par exemple, une suite d'au moins un chiffre devient un seul remplacement :
printf 'id=123\n' | sed -E 's/[0-9]+/N/'
La sortie est id=N. Cette option change la syntaxe de certains opérateurs ; elle ne rend pas le motif littéral. Choisissez la forme comprise par votre implémentation et testez-la sur les données réelles avant toute modification de fichier.
Modifier une copie avec sauvegarde et vérifier la différence
Après avoir contrôlé all.txt, créez une copie indépendante à modifier. La commande GNU -i.bak sauvegarde le contenu précédent sous le nom terminé par .bak :
(
set -eu
cp config.txt editable.txt
sed -i.bak 's/red/green/g' editable.txt
diff -u editable.txt.bak editable.txt || test "$?" -eq 1
cmp config.txt editable.txt.bak
)
Le résultat de diff montre les anciennes lignes précédées de - et les nouvelles précédées de +. Son statut 1 signifie que des différences ont été trouvées ; le test accepte précisément ce résultat de comparaison. Un autre statut d'erreur ne doit pas être considéré comme une différence normale.
Le contrôle avec cmp ne produit rien et réussit si la sauvegarde contient exactement les mêmes octets que config.txt. Les fichiers d'exercice sont neufs : sur des données existantes, vérifiez aussi qu'un nom de sauvegarde déjà présent ne sera pas remplacé lors d'une nouvelle édition.
Sans suffixe de sauvegarde, GNU sed -i modifie le fichier sans créer cette copie. Évitez particulièrement une combinaison de -n et -i sans affichage explicite : si aucune ligne n'est produite, le fichier peut devenir vide. Vérifiez le flux sans édition sur place avant d'appliquer la modification.
Restaurer le contenu et retenir les options
Pour revenir au contenu d'origine dans notre copie d'exercice :
cp editable.txt.bak editable.txt
cmp config.txt editable.txt
cat editable.txt
red car
red red
Le contrôle silencieux de cmp confirme l'égalité du contenu restauré, puis cat affiche les deux lignes initiales. Il s'agit d'une vérification des octets du fichier, pas d'une vérification de toutes ses métadonnées ou des dépendances d'une application. Sur un fichier de configuration réel, contrôlez aussi le format attendu et le fonctionnement du service concerné.
| Option ou commande | Effet |
|---|---|
s/motif/texte/ |
Remplacer la première correspondance de chaque ligne. |
s/motif/texte/g |
Remplacer toutes les correspondances de la ligne. |
-n |
Désactiver l'affichage automatique. |
-e script |
Ajouter une règle au script d'édition. |
-E |
Employer des expressions régulières étendues. |
-i.bak |
Avec GNU sed, modifier sur place en créant une sauvegarde suffixée. |
Une redirection vers un nouveau fichier est souvent préférable pour relire le résultat avant remplacement. Ne redirigez jamais la sortie directement vers le fichier d'entrée, car le shell peut le vider avant sa lecture. Le manuel officiel de GNU sed décrit le cycle de traitement, les substitutions et les règles d'édition sur place.




