Commande sed : utilisation et exemples

sed (stream editor) est une commande linux puissante pour effectuer des opérations de texte.
Il peut effectuer une manipulation de texte de base sur des fichiers et des flux d'entrée tels que des pipes. Avec SED, vous pouvez rechercher, trouver et remplacer, insérer et supprimer des mots et des lignes. Il prend en charge des expressions régulières de base et étendues qui vous permettent de faire correspondre des modèles complexes.

Malheureusement, ce n'est pas une commande simple à prendre en main.
Mais grâce à ce tutoriel complet, vous trouverez tous les exemples d'utilisations de la commande sed avec des explications claires.
De quoi, bien comprendre le fonctionnement de sed.

Commande sed : utilisation et exemples

Que fait la commande sed ?

SED est un éditeur de flux qui fonctionne sur une entrée de commandes ou des fichiers de texte.
Il n'a toutefois pas une interface d'éditeur de texte interactive.
Au lieu de cela, vous fournissez des instructions à suivre comme cela fonctionne dans le texte. Tout cela fonctionne dans Bash et d'autres Shell de ligne de commande.

Avec sed, vous pouvez effectuer les opérations de texte suivantes :

  • Sélectionnez le texte (Chercher)
  • Substituer du texte (Chercher/Remplacer)
  • Ajouter des lignes au texte
  • Supprimer des lignes du texte Modifier (ou conserver) un fichier original

La recherche de motif peut se faire sur un caractère, suite de caractères mais aussi par des expressions régulières.

Commande sed : utilisation et exemples

Imaginons le texte suivant dans le fichier rose-tatoo.txt :

1  The pictures tell the story
2  This life had many shades
3  I'd wake up every morning and before I'd start each day
4  I'd take a drag from last nights cigarette
5  That smoldered in its tray
6  Down a little something and then be on my way
7
8  I traveled far and wide
9  And laid this head in many ports
10  I was guided by a compass
11  I saw beauty to the north
12  I drew the tales of many lives
13  And wore the faces of my own
14  I had these memories all around me
15  So I wouldn't be alone
Contenu d'un fichier texte sur Linux

Sélectionner des lignes d'un fichier texte

Pour sélectionner du texte, on utilise le flag p (print).

Voici un exemple d'utilisation de sed pour sélectionner de la ligne 1 à la ligne 4 :

sed -n '1,4p' rose-tatoo.txt
Sélectionner des lignes d'un fichier texte avec la commande sed

Si l'on désire sélectionner des portions spécifiques de texte avec différentes intervalles de lignes, on peut utiliser l'option -e.
Cela permet de combiner plusieurs sélections de texte.
Par exemple pour afficher les lignes de 1 à 4 et de 5 à 10 d'un fichier :

sed -n -e '1,4p' -e '5,10p' rose-tatoo.txt
Sélectionner des lignes d'un fichier texte avec la commande sed

Le premier numéro indique la ligne de départ.
Le deuxième numéro dit SED Quelles lignes après la ligne de départ que nous voulons voir.
Le numéro 2 signifie chaque deuxième ligne, 3 signifie chaque troisième ligne, etc.

sed -n '1~2p' rose-tatoo.txt

Nous pouvons également choisir une ligne de départ et dire à sed de passer à travers le fichier et d'imprimer des lignes alternées pour ignorer un nombre de lignes.
La commande est similaire à celle que nous avons utilisée ci-dessus pour sélectionner une plage. Cette fois, cependant, nous utiliserons un tilde (~) au lieu d'une virgule pour séparer les chiffres.

Par exemple pour afficher toutes les deux 2 lignes d'un fichier à partir de la ligne 1 :

sed -n '1~2p' rose-tatoo.txt

Pour afficher toutes les 3 lignes à partir de la ligne 1 :

sed -n '1~3p' rose-tatoo.txt
Sélectionner des lignes d'un fichier texte avec la commande sed

Encadrer un texte entre deux motifs

Pour supprimer toutes les lignes d'un texte entre deux motifs, on utilise le flag d (delete) avec la syntaxe suivante :

sed '/motif1/,/motif2/d' [fichier]

Par exemple pour supprimer les lignes entre les lignes avec I Traveled (ligne 8) et I had (ligne 14), on utilise sed comme ceci :

sed '/I traveled/,/I had/d' rose-tatoo.txt

Ainsi, on passe de la ligne 7 à la ligne 15.

Encadrer un texte entre deux motifs avec la commande sed

Chercher motif dans texte

sed est un outil très utile pour rechercher des motifs dans un texte.
Il est tout aussi puissant que la commande grep.

La syntaxe à utiliser est la suivante :

sed -n '/motif/p' [fichier]

Par exemple pour chercher toutes les lignes commençant par une tabulation puis suivi des chiffres de 10 à 19.
Ce qui dans notre cas fait ressortir les lignes de 10 à 19.
Ici on utilise des expressions régulières :

  • Le caractère ^ indique de capturer le début de la ligne
  • Puis \t indique que l'on cherche une tabulation
  • Enfin [1-9][0-9] demande capturer les caractère de 10 à 19. On aurait aussi pu écrire [0-9]{2}
sed -n "/^\t[1-9][0-9]/p" rose-tatoo.txt

Bien sûr, en reprenant les explications précédentes, il est plus rapide d'afficher par numéro de lignes :

sed -n '10,19p' rose-tatoo.txt
Chercher motif dans texte avec la commande sed

Pour afficher les lignes contenant l'expression I'd.
Ici on entoure la commande sed par des apostrophes car I'd contient le caractère '.
Cela évite de l'échapper.

sed -n "/I'd/p" rose-tatoo.txt

Remplacer chaines de caractères, texte (Subtitution)

Maintenant que l'on sait chercher du texte, on peut le remplacer.
En effet, sed est capable de substituer du texte provenant d'une commande ou sur un fichier (plus bas).
Voici la syntaxe pour effectuer du chercher et remplacer dans une chaines de caractères, texte.

sed -n 's/motif_a_chercher/texte_remplacement/g' [texte]
  • Le s dit à SED Ceci est une substitution.
  • La première chaîne est le modèle de recherche
  • La seconde est le texte avec lequel nous souhaitons remplacer ce texte correspondant

Par exemple ici, on remplace le mot Ubuntu par Debian :

echo "J'aime Ubuntu"| sed 's/Ubuntu/Debian/g'
Remplacer chaines de caractères, texte (Subtitution) avec la commande sed

Comme toute commande Linux, sed est sensible à la casse.
Ainsi, si on demande de remplacer le mot ubuntu, cela ne fonctionnera pas.
Pour rendre sed insensible à la casse, on ajoute i à la fin :

echo "J'aime Ubuntu"| sed 's/ubuntu/Debian/gi'
Remplacer chaines de caractères, texte (Subtitution) avec la commande sed

La syntaxe pour rechercher et remplacer un texte dans un fichier est la même.
Par exemple pour remplacer toutes les occurrences "I " ou "I'd" par "We" :

sed "s/I/We/g" rose-tatoo.txt
Remplacer chaines de caractères, texte (Subtitution) avec la commande sed

Bien sûr, on peut rediriger la sortie de la console vers un autre fichier grâce à > :

sed -r "s/I/We/g" rose-tatoo.txt > rose-tatoo-new.txt

Le flag g pour global indique de remplacer toutes les occurrences du fichier.
Si on ne spécifie pas /g, sed remplace la première occurrence de la ligne mais pas les suivantes.
Ainsi, dans cette phrase, I n'est remplace qu'une seule fois :

We'd wake up every morning and before I'd start each day
Remplacer chaines de caractères, texte (Subtitution) avec la commande sed

On peut aussi indiquer quelle occurrence d'une ligne remplacer à travers son numéro.
Par exemple pour remplacer la première occurrence utilisez /1, pour remplacer la seconde occurrence utilisez /2, etc.

sed "s/I/We/2" rose-tatoo.txt
Remplacer chaines de caractères, texte (Subtitution) avec la commande sed

Pour limiter le chercher remplace à une ligne en particulier, par exemple la seconde ligne :

sed '2 s/lorem/Lorem/' content.txt

Pour que la substitution se fasse sur toute la ligne, ajoutez /g :

sed "3 s/I/We/g" rose-tatoo.txt
Remplacer chaines de caractères, texte (Subtitution) avec la commande sed

Dernier exemple, où l'on supprime les numéros de lignes entre les deux tabulations de notre fichier.
Toutefois à la fin de ce didacticiel, vous verrez que l'on peut aussi supprimer des lignes de texte avec sed.

sed -r 's/^\t[0-9]{1,}\t//g' rose-tatoo.txt

L'option -r demande à sed d'utiliser les regex étendues.

Remplacer chaines de caractères, texte (Subtitution) avec la commande sed

Remplacer une chaîne de texte dans un fichier

Pour remplacer directement dans un fichier, on utilise la commande sed exactement de la même manière.
Simplement pour rechercher et remplacer une chaîne de texte dans un fichier, on ajoute l'option -i :

sed -i "s/I/We/g" rose-tatoo.txt

De ce fait sed n'imprime rien sur la sortie du terminal.

Remplacer une chaîne de texte dans le fichier avec la commande sed

Supprimer une chaîne de caractère

On peut aussi supprimer une occurrence en ne spécifiant aucun texte à remplacer.
Par exemple pour supprimer morte de malekalmorte :

echo "www.malekalmorte.com"| sed 's/morte//g'
www.malekal.com

Remplacer plusieurs motifs à la fois en une seule commande sed

On peut aussi utiliser l'option -e pour effectuer une succession de rechercher/remplacer d'un motif.
Cela permet de remplacer plusieurs motifs à la fois en une seule commande sed.
Ainsi, pour remplacer deux chaînes de caractères avec la commande sed :

sed -e 's/I/We/' -e 's/my/our/g' rose-tatoo.txt
Remplacer plusieurs motifs à la fois en une seule commande sed

Voici une autre syntaxe possible pour remplacer plusieurs motifs à la fois en une seule commande sed.
On encadre les scripts avec ' et on les sépare avec ; sauf pour le dernier.

sed 's/I/We/; s/my/our/g' rose-tatoo.txt
Remplacer plusieurs motifs à la fois en une seule commande sed

Ajouter du texte en début ou en fin de ligne

Pour ajouter du texte en début de ligne, on joue avec le caractère ^ qui demande à sed de viser le début de la ligne :

sed -e 's/^/#/' fichier.txt
Ajouter du texte en début ou en fin de ligne avec la commande sed

Pour ajouter du texte à la fin d'une ligne, il faut cette fois-ci jouer avec le caractère $.
Par exemple pour ajouter un point à la fin de ligne.
Ici nul besoin d'échapper le caractère . car nous n'utilisations pas de regex basiques ou étendues.

sed 's/$/./' rose-tatoo.txt
Ajouter du texte en début ou en fin de ligne avec la commande sed

Ainsi pour ajouter un commentaire à la fin de chaque ligne :

sed 's/$/# Ceci est un commentaire/' config.conf
Ajouter du texte en début ou en fin de ligne avec la commande sed

Le problème ici est que le commentaire s'ajoute aussi dans les lignes vides.
Pour ajouter du texte au début d'une ligne mais PAS dans les lignes vides.
!s signifie non ligne vide.

sed '/^$/!s/^/#/g' config.conf

Enfin pour ajouter du texte seulement dans les lignes vides :

sed 's/^$/Je rempli une ligne vide/' config.conf
Ajouter du texte en début ou en fin de ligne avec la commande sed

Autre syntaxe possible pour viser les lignes vides avec le caractère s :

sed '/^$/s/^/#/g' config.conf

Insérer des lignes dans un texte

Pour insérer une chaîne avant chaque ligne :

sed 'i \# je suis un commentaire' config.conf
Insérer des lignes dans un texte avec la commande sed

Pour insérer une ligne après chaque ligne :

sed 'a \# je suis un commentaire' config.conf
Insérer des lignes dans un texte avec la commande sed

Il est tout à fait possible de combiner les deux drapeaux afin d'insérer du texte avant et après :

sed 'ia \# je suis un commentaire' config.conf

Enfin pour ajouter un texte avant ou après un motif, la syntaxe est la suivante :

sed -r '/\[\w+\]/a# je suis ligne insérée' config.conf

Ici nous chercher à insérer une ligne seulement après les sections du fichier de configuration, d'où le motif suivant :

  • \[ \] pour rechercher les crochets de la section
  • \w+ n'importe quelle suite de caractères
  • le flag a
  • Enfin on insère la ligne # je suis ligne insérée
Ajouter un texte avant ou après un motif avec sed

Supprimer des lignes d'un texte

Pour supprimer des lignes, on utilise d pour delete.

Supprimer la ligne 7 d'un fichier :

sed '7d' 

Pour supprimer les 10 premières lignes d'un fichier :

sed '1,10d'

Bien entendu, il est possible de supprimer des lignes avec un motif.
Par exemple, pour supprimer la ligne comportant une tabulation et 7 :

sed '/\t7/d' rose-tatoo.txt

Autre exemple où l'on supprime toutes les lignes commentaires :

sed '/^#/d' config.conf

Supprimer la dernière ligne d'un fichier :

sed '$d'

Pour supprimer les lignes identiques et consécutives dans un fichier :

sed '$!N; /^\(.*\)\n\1$/!P; D'

A l'inverse pour supprimer toutes les lignes non identiques et consécutives :

sed '$!N; s/^\(.*\)\n\1$/\1/; t; D'

Utiliser la valeur d'une variable dans une commande sed

La commande sed peut stocker le résultat d'une recherche d'un motif dans une variable.
Pour cela, il faut l'encadrer avec des parenthèses.
On l'appelle ensuite avec \1, \2 qui correspond au numéro de la parenthèses dans le motif.
Enfin on utilise /p pour print.

Imagions que l'on cherche le mot motif.
Ici motif est encadrer dans la première parenthèse, donc on le stocke dans la variable \1.

echo "Exemple de motif à rechercher"| sed -nre 's/.*(motif).*/\1/p'
motif

Alors qu'ici, c'est la second parenthèse donc \2.

echo "Exemple de motif à rechercher"| sed -nre 's/(.*)(motif)(.*)/\2/p'
motif

Par exemple pour extraire une URL complète dans un texte :

echo "Je suis une URL https://www.malekal.com/commande-sed-utilisation-et-exemples/ a ouvrir dans un navigateur internet"|sed -nre 's/.*(https?:\/\/[a-z0-9./-]+\/).*/\1/p'
https://www.malekal.com/commande-sed-utilisation-et-exemples/

Alors que pour extraire le nom d'hôte dans un texte :

echo "Je suis une URL https://www.malekal.com/commande-sed-utilisation-et-exemples/ a ouvrir dans un navigateur internet"|sed -nre 's/.*https?:\/\/(([A-Za-z0-9_-]+\.){2,}[a-z]+)(\/.*)?.*/\1/p'
www.malekal.com
tiliser la valeur d'une variable dans une commande sed

Cela permet de stocker le résultat de la commande sed dans une variable, ce qui est utilise dans les scripts BASH.
Par exemple pour stocker la valeur de la commande sed dans une variable hote :

hote=$(echo $1|sed -nre 's/.*https?:\/\/(([A-Za-z0-9_-]+\.){2,}[a-z]+)(\/.*)?.*/\1/p')

Tags: