Chapitre 5. L'éditeur de flot GNU sed

Table des matières

1. Introduction
1.1. Qu'est-ce que sed?
1.2. commandes sed
2. Opérations d'édition de modification
2.1. Afficher les lignes contenant un patron
2.2. Exclure les lignes contenant le patron
2.3. Intervalle de lignes
2.4. Trouver et remplacer avec sed
3. L'usage en mode différé de sed
3.1. Lire des commandes sed depuis un fichier
3.2. Ecrire des fichiers de résultat
4. Résumé
5. Exercices

Résumé

A la fin de ce chapitre vous aurez connaissance des sujets suivants:

  • Qu'est-ce que sed?

  • L'usage en mode immédiat de sed

  • Les expressions régulières et l'édition de flot

  • Utiliser des commandes sed dans un script

Ceci est une introduction

Ces explications sont loin d'être complètes et certainement pas faites pour être considérées comme le manuel utilisateur de sed. Ce chapitre est seulement inclus afin de montrer quelques aspects intéressants dans les chapitres suivants, et parce que tout utilisateur avancé devrait avoir une connaissance de base de cet éditeur.

Pour plus d'informations, se référer aux pages man et info de sed.

1. Introduction

1.1. Qu'est-ce que sed?

Un éditeur de flot (Stream EDitor) est utilisé pour effectuer des transformations simples sur du texte lu depuis un fichier ou un tube (NdT: pipe). Le résultat est envoyé sur la sortie standard. La syntaxe de la commande sed ne spécifie pas de fichier de sortie, mais les résultats peuvent être mémorisés dans un fichier par le biais de redirection. L'éditeur ne modifie pas le flot d'entrée.

Ce qui distingue sed d'autres éditeurs tel vi et ed, c'est sa faculté de filtrer le texte qu'il obtient par un tube. Vous n'avez pas à interagir avec l'éditeur pendant qu'il travaille; c'est pourquoi sed est parfois appelé un éditeur par lot. Cette caractéristique vous permet d'utiliser des commandes d'édition dans un script, ce qui facilite grandement les tâches d'édition répétitives. Quand vous devez effectuer un remplacement de texte dans un grand nombre de fichiers , sed est d'une grande aide.

1.2. commandes sed

Le programme sed peut effectuer substitutions et suppressions avec des expressions régulières, comme celles utilisées avec la commande grep; voir Section 2, « Exemples en utilisant grep ».

Les commandes d'édition sont similaires à celles utilisées dans l'éditeur vi:

Tableau 5.1. Commandes d'édition Sed

CommandeEffet
a\Ajoute le texte sous la ligne courante.
c\Remplace le texte de la ligne courante par le nouveau texte.
dSupprime le texte.
i\Insère le texte au dessus de la ligne courante.
pImprime le texte.
rLit un fichier.
sCherche et remplace du texte.
wEcrit dans un fichier.

A part les commandes d'édition, vous pouvez donner des options à sed. Un aperçu se trouve dans le tableau ci-dessous:

Tableau 5.2. Options Sed

OptionEffet
-e SCRIPTAjoute les commandes de SCRIPT au jeu de commandes à exécuter sur le flot en entrée.
-fAjoute les commandes contenues dans le fichier SCRIPT-FILE au jeu de commandes à exécuter sur le flot d'entrée.
-nMode Silencieux.
-VAffiche les informations de version et s'arrête.

Les pages info de sed contiennent plus d'informations; nous ne listons ici que les commandes et les options le plus fréquemment utilisé.

2. Opérations d'édition de modification

2.1. Afficher les lignes contenant un patron

Vous pouvez le faire avec grep, bien sûr, mais vous ne pouvez faire un « chercher-remplacer » avec cette commande. Ceci est juste un début.

Voici notre fichier texte d'exemple:

sandy ~> cat -n exemple
     1  This is the first line of an example text.
     2  It is a text with erors.
     3  Lots of erors.
     4  So much erors, all these erors are making me sick.
     5  This is a line not containing any errors.
     6  This is the last line.

sandy ~>

Nous voulons que sed trouve toutes les lignes contenant le patron ciblé, dans ce cas « erors ». Nous employons le p pour obtenir le resultat:

sandy ~> sed  '/erors/p' exemple
This is the first line of an example text.
It is a text with erors.
It is a text with erors.
Lots of erors.
Lots of erors.
So much erors, all these erors are making me sick.
So much erors, all these erors are making me sick.
This is a line not containing any errors.
This is the last line.

sandy ~>

Comme vous l'avez remarqué, sed affiche le fichier entier, mais les lignes contenant la cible sont affichées 2 fois. Ce n'est pas ce qu'on veut. De sorte à n'afficher que les lignes contenant la cible, employez l'option -n :

sandy ~> sed -n '/erors/p' exemple
It is a text with erors.
Lots of erors.
So much erors, all these erors are making me sick.

sandy ~>

2.2. Exclure les lignes contenant le patron

Nous utilisons le même exemple de fichier texte. Maintenant nous voulons seulement voir les lignes qui ne contiennent pas la chaîne cible:

sandy ~> sed '/erors/d' exemple
This is the first line of an example text.
This is a line not containing any errors.
This is the last line.

sandy ~>

La commande d a pour effet d'exclure des lignes de l'affichage.

Les lignes dont le début correspond à un patron donné et la fin à un autre sont affichées comme ça:

sandy ~> sed -n '/^This.*errors.$/p' exemple
This is a line not containing any errors.

sandy ~>

2.3. Intervalle de lignes

Cette fois nous voulons supprimer les lignes contenant les erreurs. Dans l'exemple ce sont les lignes 2 à 4. Spécifier cet intervalle avec la commande d:

sandy ~> sed '2,4d' exemple
This is the first line of an example text.
This is a line not containing any errors.
This is the last line.

sandy ~>

Pour afficher le fichier à partir d'une certaine ligne jusqu'à la fin, employez une commande de la sorte:

sandy ~> sed '3,$d' exemple
This is the first line of an example text.
It is a text with erors.

sandy ~>

Ceci affiche seulement les 2 premières lignes du fichier exemple.

Les commandes suivantes affichent la première ligne contenant le patron « a text », jusqu'à et inclus la prochaine ligne contenant « a line »:

sandy ~> sed -n '/a text/,/This/p' exemple
It is a text with erors.
Lots of erors.
So much erors, all these erors are making me sick.
This is a line not containing any errors.

sandy ~>

2.4. Trouver et remplacer avec sed

Dans cet exemple de fichier, nous allons maintenant chercher et remplacer les erreurs au lieu de seulement sélectionner les lignes contenant la cible.

sandy ~> sed 's/erors/errors/' exemple
This is the first line of an example text.
It is a text with errors.
Lots of errors.
So much errors, all these erors are making me sick.
This is a line not containing any errors.
This is the last line.

sandy ~>

Comme vous le constatez, ce n'est pas exactement l'effet désiré: en ligne 4, seulement la première occurrence de la chaîne a été remplacée, et il reste encore un 'eror'. Employer la commande g pour indiquer à sed que il doit traiter la ligne entière plutôt que de stopper à la première occurrence trouvée:

sandy ~> sed 's/erors/errors/g' exemple
This is the first line of an example text.
It is a text with errors.
Lots of errors.
So much errors, all these errors are making me sick.
This is a line not containing any errors.
This is the last line.

sandy ~>

Pour insérer une chaîne au début de chaque ligne du fichier, par exemple pour citer:

sandy ~> sed 's/^/> /' exemple
> This is the first line of an example text.
> It is a text with erors.
> Lots of erors.
> So much erors, all these erors are making me sick.
> This is a line not containing any errors.
> This is the last line.

sandy ~>

Insérer une chaîne à la fin de chaque ligne:

sandy ~> sed 's/$/EOL/' exemple
This is the first line of an example text.EOL
It is a text with erors.EOL
Lots of erors.EOL
So much erors, all these erors are making me sick.EOL
This is a line not containing any errors.EOL
This is the last line.EOL

sandy ~>

Commandes de recherche et remplacement multiples sont séparées avec l'option -e :

sandy ~> sed -e 's/erors/errors/g' -e 's/last/final/g' exemple
This is the first line of an example text.
It is a text with errors.
Lots of errors.
So much errors, all these errors are making me sick.
This is a line not containing any errors.
This is the final line.

sandy ~>

Garder à l'esprit que sed par défaut affiche les résultats sur la sortie standard, le plus souvent sur la fenêtre de votre terminal. Si vous voulez sauvegarder le résultat dans un fichier, le rediriger:

sed option 'some/expression' file_to_process > sed_output_in_a_file

Plus d'exemples

Plein d'exemples sed se trouvent dans les scripts de démarrage de votre machine, lesquels sont d'ordinaire dans /etc/init.d ou /etc/rc.d/init.d. Placez-vous dans le répertoire contenant les scripts d'initialisation de votre système et lancer la commande suivante:

grep sed *

3. L'usage en mode différé de sed

3.1. Lire des commandes sed depuis un fichier

De multiple commandes sed peuvent être mémorisées dans un fichier et exécutées avec l'option -f . Quand un tel fichier est créé, assurez-vous que:

  • Aucun espace n'est présent à la fin des lignes.

  • Aucune apostrophe n'est employée.

  • Quand vous entrez du texte à ajouter ou remplacer, toute sauf la dernière ligne finit par un slash inversé.

3.2. Ecrire des fichiers de résultat

Produire ce fichier se fait avec l'opérateur de redirection de sortie >. Ceci est un script d'exemple utile à la création de fichier HTML très simple à partir de fichiers texte simples.

sandy ~> cat script.sed
1i\
<html>\
<head><title>sed generated html</title></head>\
<body bgcolor="#ffffff">\
<pre>
$a\
</pre>\
</body>\
</html>

sandy ~> cat txt2html.sh
#!/bin/bash

# Ceci est un script simple pour convertir du texte en HTML.
# D'abord nous éliminons tous les caractères de saut de ligne, de sorte que l'ajout
# ne se produise qu'une fois, puis nous remplaçons les sauts de ligne.

echo "converting $1..."

SCRIPT="/home/sandy/scripts/script.sed"
NAME="$1"
TEMPFILE="/var/tmp/sed.$PID.tmp"
sed "s/\n/^M/" $1 | sed -f $SCRIPT | sed "s/^M/\n/" > $TEMPFILE
mv $TEMPFILE $NAME

echo "done."

sandy ~>

$1 stocke le premier paramètre d'une commande donnée, dans ce cas le nom du fichier à convertir:

sandy ~> cat test
line1
line2
line3

Plus sur les paramètres positionnels au Chapitre 7, Les instructions de condition.

sandy ~> txt2html.sh test
converting test...
done.

sandy ~> cat test
<html>
<head><title>sed generated html</title></head>
<body bgcolor="#ffffff">
<pre>
line1
line2
line3
</pre>
</body>
</html>

sandy ~>

Ce n'est pas vraiment la bonne méthode; c'est juste un exemple pour démontrer le potentiel de sed. Voir la Section 3, « Les variables Gawk » pour une solution plus décente à ce problème, avec les constructions awk BEGIN et END.

sed facile

Les éditeurs sophistiqués, permettant la mise en relief de la syntaxe, reconnaissent la syntaxe sed. Cela peut être d'une grande aide si vous avez tendance à oublier des slashs inversés.

4. Résumé

L'éditeur par lot sed est un outil puissant de travail sur une ligne, lequel peut traiter des flots de données: il peut prendre en entrée les lignes depuis un tube. Ce qui le rend pratique pour un usage différé. L'éditeur sed utilise des commandes de type vi et accepte les expressions régulières.

L'outil sed peut lire des commandes depuis la ligne de commande ou depuis un script. Il est souvent employé pour effectuer des chercher-remplacer sur des lignes contenant un patron.

5. Exercices

Ces exercices sont faits pour montrer plus avant ce que sed peut faire.

  1. Afficher une liste des fichiers de votre répertoire de scripts qui se finissent par « .sh ». Pensez que vous devrez peut-être supprimer l'alias ls. Mettre le résultat dans un fichier temporaire.

  2. Faire une liste des fichiers de /usr/bin qui ont la lettre « a » en second caractère. Mettre le résultat dans un fichier temporaire.

  3. Supprimer les 3 premières lignes de chaque fichier temporaire.

  4. Afficher sur la sortie standard seulement les lignes contenant le patron « an ».

  5. Créer un fichier contenant les commandes sed pour effectuer les 2 tâches précédentes. Ajouter une commande supplémentaire à ce fichier qui ajoute une chaîne comme « *** Ceci pourrait avoir quelque chose à voir avec man et les pages man *** » dans la ligne précédant chaque occurrence de la chaîne « man ». Vérifier les résultats.

  6. Une liste étendue du répertoire racine, /, est utilisée en entrée. Créer un fichier stockant les commandes sed qui cherchent les liens symboliques et les fichiers simples. Si un fichier est un lien symbolique, faire précéder la ligne de « --Ceci est un symlink-- ». Si le fichier est un fichier simple, mettre un message sur la ligne, en ajoutant un commentaire du genre « <--- Ceci est un fichier simple ».

  7. Créer un script qui affiche les lignes, prises dans un fichier, contenant des espaces à la fin. Ce script devrait faire appel à un script sed et afficher des informations utiles à l'utilisateur.