Appearance
sed - Manipulation du contenu d'un fichier
La manipulation de contenus textuels en ligne de commande constitue un pilier fondamental de l'administration système et du traitement de données.
sed
sed (stream editor) est un éditeur de flux non-interactif destiné à l'édition de texte ligne par ligne, idéal pour rechercher, remplacer, supprimer ou ajouter du contenu directement dans des fichiers, sans avoir besoin de les ouvrir dans un éditeur classique.
Il peut effectuer une manipulation de texte de base sur des fichiers et des flux d’entrée tels que des pipes. Il prend en charge des expressions régulières qui permettent de faire correspondre des modèles complexes.
Syntaxe de base
bash
sed [options] 'commande' [fichier][options]: comme-ipour éditer en placecommande: une ou plusieurs instructions à appliquer (par exemplespour substitution,dpour suppression…)[fichier]: fichier cible (facultatif, sinonsedlit depuis l’entrée standard)
sed utilise une commande, c’est-à-dire une chaîne de caractères qui indique clairement le type d’opération à effectuer. On peut chaîner plusieurs commandes avec -e ou les séparer par ;, et charger un fichier de script avec -f script.sed.
La syntaxe des commandes est :
s/modèleRecherché/remplacement/drapeau(x)
⚠️
Si le modèleRecherché ou le remplacement contient le caractère /, vous pouvez utiliser un autre délimiteur, par exemple # :
bash
sed 's#modèle/recherché#remplacement#drapeau(x)' fichier.txtExemples de drapeaux :
️➡️ Sans drapeau - remplacement simple :
bash
$ cat fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs publics,bash
$ sed 's/publics/privés/' fichier.txt # Remplace la première occurrence sur chaque ligne et affiche tout
Les amoureux qui s'bécotent sur les bancs privés,
Bancs privés, bancs publics➡️ Le drapeau p (print) est particulièrement utile avec l'option -n :
bash
$ sed -n 's/amoureux/fiancés/p' fichier.txt # Affiche UNIQUEMENT les lignes modifiées
Les fiancés qui s'bécotent sur les bancs publics,- L'option
-ndésactive l'affichage automatique de toutes les lignes. - Le drapeau
pdemande d'afficher les lignes où un remplacement a été fait. - La combinaison des deux permet de voir UNIQUEMENT les lignes qui ont été modifiées.
Sans l'option -n, le drapeau p cause un double affichage :
bash
$ sed 's/publics/privés/p' fichier.txt # Affiche toutes les lignes + lignes modifiées en double
Les amoureux qui s'bécotent sur les bancs privés,
Les amoureux qui s'bécotent sur les bancs privés,
Bancs privés, bancs publics,
Bancs privés, bancs publics,➡️ Exemple avec le drapeau g (global) - tous les remplacements :
bash
$ cat fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs publics,bash
$ sed 's/publics/privés/g' fichier.txt
Les amoureux qui s'bécotent sur les bancs privés,
Bancs privés, bancs privés,Le drapeau g indique que la substitution doit être effectuée globalement sur chaque ligne (toutes les occurrences).
Si on omet le drapeau g, seule la première occurrence de chaque ligne sera remplacée :
bash
$ cat fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs publics,bash
$ sed 's/publics/privés/' fichier.txt
Les amoureux qui s'bécotent sur les bancs privés,
Bancs privés, bancs publics,Substitution : Remplacer toutes les occurrences d'un mot par un autre. s (substitute)
bash
$ sed 's/ancien/nouveau/g' fichier.txt # Affiche le résultat dans le terminal sans modifier le fichierOption -i ️
Par défaut, sed affiche le résultat dans le terminal sans modifier le fichier original.
Pour effectuer les modifications directement dans le fichier, utilisez l'option -i :
bash
$ sed -i 's/ancien/nouveau/g' fichier.txt # Modifie le fichier directementCréer une copie de sauvegarde avant modification :
bash
sed -i.bak 's/root/admin/g' fichier.txtLe fichier fichier.txt.bak est créé automatiquement.
Suppression de lignes : Supprimer les lignes contenant un motif spécifique. d (delete)
bash
$ cat fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs publics,bash
$ sed '/qui/d' fichier.txt
Bancs publics, bancs publics,Suppression par intervalle de lignes
Supprimer les lignes 7 à 9 inclus :
bash
$ sed '7,9d' fichier.txtPour supprimer une seule ligne, par exemple la ligne 7 :
bash
$ sed '7d' fichier.txtModification de lignes spécifiques : Appliquer une commande uniquement à une ligne donnée. c (change)
bash
$ cat fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs publics,bash
$ sed '2c Ligne modifiée' fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Ligne modifiéeRemplacer une ligne contenant un motif spécifique. c (change)
bash
$ sed '/bancs/c Ligne remplacée' fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Ligne remplacéeInsertion de texte : Ajouter du texte avant ou après une ligne spécifique. i (insert) et a (append)
Rechercher un motif et insérer du texte avant ou après cette ligne :
bash
$ sed '/bancs/i Texte avant' fichier.txt
Texte avant
Les amoureux qui s'bécotent sur les bancs publics,
Texte avant
Bancs publics, bancs publics,bash
$ sed '/bancs/a Texte après' fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Texte après
Bancs publics, bancs publics,
Texte aprèsAjouter une ligne à une position spécifique, par exemple en début de fichier :
bash
$ sed '1i\Ligne insérée en haut' fichier.txt
Ligne insérée en haut
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs publics,Insertion de plusieurs lignes à la suite (une commande par ligne insérée) :
bash
sed -e '3a\Ligne A' -e '3a\Ligne B' fichier.txtEnchaîner des commandes -e
L’option « -e » permet d’enchaîner plusieurs commandes une à la suite des autres, exactement comme avec grep
bash
# Remplacer "ancien" par "nouveau" et supprimer les lignes contenant "motif"
$ sed -e 's/ancien/nouveau/g' -e '/motif/d' fichier.txtUtiliser des regex étendues -r ou -E
bash
$ cat fichier.txt
1 Les amoureux qui s'bécotent sur les bancs publics,
2 Bancs publics, bancs publics,bash
# Remplacer les numéros de ligne par des tirets
$ sed -E 's/[0-9]+ /- /g' fichier.txt
- Les amoureux qui s'bécotent sur les bancs publics,
- Bancs publics, bancs publics,Remarque portabilité:
- Sur GNU sed (Linux),
-Eet-rsont acceptés;-Eest la forme moderne. - Sur macOS/BSD sed, utilisez
-E(pas-r).
^ et $ : Ancrages de début et fin de ligne
^ correspond au début d'une ligne, tandis que $ correspond à la fin d'une ligne.
bash
$ cat fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs publics,bash
# Ajouter du texte au début et à la fin de chaque ligne
$ sed -e 's/^/DEBUT: /' -e 's/$/ :FIN/g' fichier.txt
DEBUT: Les amoureux qui s'bécotent sur les bancs publics, :FIN
DEBUT: Bancs publics, bancs publics, :FINSupprimer les lignes vides ou contenant uniquement des espaces :
bash
sed '/^[[:space:]]*$/d' fichier.txtN-ième occurrence : appliquer la substitution uniquement à la N-ième occurrence sur chaque ligne
bash
$ cat fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs publics,bash
# Remplacer uniquement la 2ème occurrence de "publics" par "privés"
$ sed 's/publics/privés/2' fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs privés,Limiter la substitution à une ligne spécifique
Pour limiter remplacement à une ligne en particulier, par exemple la seconde ligne :
bash
$ cat fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs publics, bancs publics,bash
$ sed '2s/publics/privés/g' fichier.txt
Les amoureux qui s'bécotent sur les bancs publics,
Bancs privés, bancs privés,Adresses et plages (numéros et motifs)
Limiter l'application d'une commande à des lignes précises:
- Par numéros:
M,Ndésigne une plage (inclusif)
bash
sed '10,20d' fichier.txt # Supprimer les lignes 10 à 20
sed '2s/foo/bar/' fichier.txt # Remplacer seulement à la ligne 2- Par motifs:
/A/,/B/désigne la plage entre la première occurrence de A et la suivante de B
bash
sed '/BEGIN/,/END/d' fichier.txtCombiner adresses et commandes séparées par ;:
bash
# Remplacer "foo" par "bar" de la ligne 1 à 5, et afficher les lignes contenant "erreur"
sed '1,5s/foo/bar/; /erreur/p' fichier.txtGroupement de commandes { ... }
Appliquer plusieurs actions sur la même adresse ou plage:
bash
# filtrer les lignes contenant "erreur", remplacer "ERROR" par "ERREUR" et afficher la ligne modifiée
sed '/erreur/{ s/ERROR/ERREUR/g; p }' fichier.logBack-références et & dans le remplacement
&représente le texte qui a été trouvé (le motif complet)
bash
# Encadre chaque occurrence de "motif" par des crochets
sed 's/motif/[&]/g' fichier.txt\1,\2, ... réutilisent les groupes capturés (avec-Epour la lisibilité)
bash
sed -E 's/^([^,]+), ([^,]+)/\2 \1/' noms.txt # "Nom, Prénom" -> "Prénom Nom"
# | | | |- \1 Affiche le 1er groupe capturé
# | | |- \2 Affiche le 2e groupe capturé
# | |- [^,]+ capture tout les caractères avant la virgule
# |- ^ début de ligne[^,]+: correspond à une séquence de un ou plusieurs caractères qui ne sont pas des virgules.
⚠️ notes sur les back-références:
- Sans
-E, les parenthèses doivent être échappées :\( ...\) - Dans le remplacement, utilisez
\\1,\\2, ... si vous n'utilisez pas de guillemets simples. - Les back-références se réfèrent aux groupes capturés dans le modèle de recherche, numérotés de gauche à droite.
Contrôle de l'affichage et du flux -n, p, q
- Afficher seulement les lignes modifiées:
bash
sed -n 's/foo/bar/p' fichier.txt- S'arrêter après le premier match (utile en performance):
bash
sed '/critique/{p;q}' fichier.txtScripts sed -f
Écrire des commandes dans un fichier script.sed et l'appliquer:
sed
# contenu de script.sed
s/foo/bar/g
/erreur/pbash
sed -f script.sed fichier.txtÉdition de plusieurs fichiers
Il est possible d’appliquer une commande sed à plusieurs fichiers en une seule fois en utilisant des jokers (wildcards) ou en listant les fichiers.
bash
$ sed -i 's/ancien/nouveau/g' *.txt
$ sed -i 's/ancien/nouveau/g' fichier1.txt fichier2.txtCheat sheet sed (rapide)
Syntaxe
sed [options] 'commande(s)' [fichier]- Chaîner:
-e 'cmd1' -e 'cmd2'ou séparer par;• Script:-f script.sed - Regex étendues:
-E(GNU/BSD) • Délimiteur alternatif:s#...#...#
Commandes
- Substitution:
s/pattern/remplacement/[flags]→ 1ère:s/foo/bar/• global:s/foo/bar/g• N‑ième:s/foo/bar/2 - Suppression: motif
'/motif/d'• plage'10,20d'• entre motifs'/A/,/B/d' - Impression ciblée:
-n 's/foo/bar/p' - Insertion/Append/Changement:
i,a,c(souvent avec fin de ligne\)
- Substitution:
Adresses (où appliquer)
- Ligne:
N• Plage:M,N• Motif:/motif/• Plage motifs:/A/,/B/ - Exemple:
'1,5s/foo/bar/; /erreur/p'
- Ligne:
Flags de
s///g(toutes) •N(N‑ième) •p(imprime si remplacé) •I(insensible à la casse, GNU) •w fichier(écrit)
Regex utiles
- Ancres:
^début,$fin • POSIX:[[:digit:]],[[:alpha:]],[[:space:]] - Avec
-E: alternancex|y, groupes(...), quantificateurs+ ? {m,n}
- Ancres:
Remplacement avancé
- Texte trouvé:
&→s/motif/[&]/g - Groupes capturés:
\1,\2→-E 's/^([^,]+), ([^,]+)/\2 \1/'
- Texte trouvé:
Affichage/flux
- Mode silencieux:
-n• Imprimer:p• Quitter tôt:q→'/critique/{p;q}' - Grouper des actions:
{ ... }→'/err/{ s/x/y/g; p }'
- Mode silencieux:
Édition en place
- GNU/Linux:
-i.bak 's/foo/bar/g' fichier(sauvegarde*.bak) - macOS/BSD:
-i '' -e 's/foo/bar/g' fichier
- GNU/Linux:
Trucs
- Supprimer lignes vides:
'/^[[:space:]]*$/d' - Préfixe/suffixe:
-e 's/^/DEBUT: /' -e 's/$/ :FIN/' - Plusieurs fichiers:
-i 's/ancien/nouveau/g' *.txt
- Supprimer lignes vides:
Pratique 💃
Voir les exercices sur Gitlab: https://gitlab.com/16d/420-16d-exercices/-/tree/main/sed