Sed

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Traitement de flux texte (édition non interactive)
Commande sed
Contexte Substitution en masse, extraction de lignes, scripts shell
Voir aussi Grep, Awk (souvent combinés avec sed)

sed (stream editor) applique des commandes d'édition à un flux de texte, ligne par ligne, sans ouvrir de fichier dans un éditeur interactif. C'est l'outil de référence pour la substitution en masse, l'extraction de lignes selon un motif, ou la modification de fichiers directement depuis un script shell.

Syntaxe de base

sed -e "s/cherche/remplace/"      # affiche le résultat sur la sortie standard (n'écrit rien)
sed -i "s/cherche/remplace/g"     # modifie le fichier en place, g = toutes les occurrences par ligne

sed "s/tache/blancheur/g" mon_fichier > mon_fichier_propre   # sans -i : redirection vers un nouveau fichier

Sans le flag g, seule la première occurrence de chaque ligne est remplacée. Plusieurs commandes peuvent être chaînées avec plusieurs -e :

sed -e 's/$/./' -e 's/.*tache.*/\0/'   fichier   # deux commandes appliquées dans l'ordre

⚠️ sed -i modifie le fichier sans sauvegarde par défaut. Pour garder une copie de sécurité : sed -i.bak "s/cherche/remplace/g" fichier (crée fichier.bak avant modification).

Commandes principales

  • s — substitution (s/motif/remplacement/drapeaux)
  • p — afficher la ligne
  • d — supprimer la ligne
  • n — passer à la ligne suivante
  • q — quitter (éventuellement après N lignes : sed '3q')
  • w fichier — écrire la ligne dans un fichier
  • r fichier — insérer le contenu d'un fichier
  • a, i, c — ajouter après / insérer avant / remplacer la ligne

Adressage : sélectionner des lignes

sed applique une commande soit à tout le flux, soit à une sélection de lignes précédée d'une adresse :

sed -n '3p' fichier                       # affiche uniquement la ligne 3
sed -n '3,6p' fichier                     # affiche les lignes 3 à 6
sed -n '$p' fichier                       # affiche la dernière ligne
sed -n '/motif/p' fichier                 # affiche les lignes contenant "motif"
sed -n '/debut/,/fin/p' fichier           # affiche l'intervalle entre deux motifs (inclus)
sed -n '/debut/,8p' fichier               # affiche du motif jusqu'à la ligne 8
sed -n '3{p;q}' fichier                   # affiche la ligne 3 et s'arrête (plus rapide sur un gros fichier)

-n désactive l'affichage automatique de chaque ligne : sans lui, p afficherait chaque ligne deux fois. Le séparateur /.../ peut être remplacé par n'importe quel caractère (utile si le motif contient lui-même des /) :

sed -n '\#/var/log#p' fichier             # équivalent à '/\/var\/log/p' mais plus lisible

Ajouter, insérer, remplacer des lignes

sed -e '$a\texte ajouté'          fichier   # ajoute une ligne en fin de fichier
sed -e '2a\texte ajouté'         fichier   # ajoute une ligne après la ligne 2
sed -i '1itexte inséré'          fichier   # insère une ligne au tout début du fichier
sed -e '/motif/i\texte inséré'   fichier   # insère avant chaque ligne correspondant à "motif"
sed -e '/motif/c\texte remplaçant' fichier # remplace la ligne correspondant à "motif"

Supprimer des lignes

sed -i '/motif/d' fichier          # supprime les lignes contenant "motif"
sed -i '10d' fichier               # supprime la ligne 10
sed -i '1,55d' fichier             # supprime les lignes 1 à 55

Cas pratiques

Mettre en majuscule la première lettre d'une chaîne (extension GNU) :

echo toto | sed 's/^./\U&/'        # \U met en majuscule le caractère capturé par &

Supprimer les espaces en début et fin de ligne :

sed 's/^[ \t]*//;s/[ \t]*$//' fichier

Fusionner toutes les lignes en une seule (utile avant un traitement global) :

sed -i ':a;N;$!ba;s/\n/--/g' fichier   # boucle N/ba pour charger tout le fichier avant substitution

Conversion fins de ligne Windows ↔ Unix^M représente le retour chariot (CR), à saisir dans le terminal avec Ctrl+V puis Ctrl+M :

sed 's/^M$//' fichier              # supprime le CR en fin de ligne (Windows → Unix)
sed 's/$/^M/'  fichier             # ajoute un CR en fin de ligne (Unix → Windows)

Plus simple et plus lisible en pratique : dos2unix / unix2dos s'ils sont installés, qui font exactement ça sans jonglage de caractères de contrôle.

Afficher un intervalle de lignes dans un gros fichier via des variables shell :

sed -n "${LIGNE1},${LIGNE2}p;${LIGNE_ARRET}q" "$FICHIER"

Traitement récursif sur plusieurs fichiers

sed n'a pas d'option récursive native : on le combine avec find :

find /mon/rep -type f -exec sed -i "s/chaine1/chaine2/g" {} \;
find . -name "*.c" -exec sed -i "s/oldWord/newWord/g" {} \;

Renommer des fichiers en remplaçant les espaces par des underscores (sed ne renomme pas les fichiers lui-même, mais illustre le même réflexe find + traitement en masse) :

find . -type f -regex ".*\ .*" -exec bash -c 'mv "$1" "${1// /_}"' _ {} \;

Voir aussi

  • Grep — recherche de motifs, souvent utilisé en amont d'un sed
  • Awk — traitement de texte plus riche (colonnes, calculs), pour aller au-delà de sed
  • Tr — substitution caractère par caractère, plus simple que sed pour ce cas d'usage