sed (Unix)

Un article de Wikipédia, l'encyclopédie libre.
(Redirigé depuis Sed (logiciel))

sed

Informations
Développé par Lee E. McMahon (en)Voir et modifier les données sur Wikidata
Première version Voir et modifier les données sur Wikidata
Système d'exploitation Type UnixVoir et modifier les données sur Wikidata
Type Programme informatique
Utilitaire UNIX (d)
Éditeur de texte
Langage de scriptVoir et modifier les données sur Wikidata

sed (abréviation de stream editor, « éditeur de flux ») est, comme awk, un programme informatique permettant d'appliquer différentes transformations prédéfinies à un flux séquentiel de données textuelles. sed lit des données d'entrée ligne par ligne, modifie chaque ligne selon des règles spécifiées dans un langage propre (appelé « script sed »), puis retourne le contenu du fichier (par défaut). Bien qu'originellement écrit pour Unix, par Lee E. McMahon (en) en 1973/1974 (Bell Labs), sed est maintenant disponible sur pratiquement tous les systèmes d'exploitation disposant d'une interface en ligne de commande.

Présentation[modifier | modifier le code]

sed est souvent décrit comme un éditeur de texte non-interactif. Il diffère d'un éditeur conventionnel en ceci que la séquence de traitement des deux flux d'informations nécessaires (les données et les instructions) est inversée. Au lieu de prendre une par une les commandes d'édition pour les appliquer à l'intégralité du texte (qui doit alors être intégralement en mémoire), sed ne parcourt qu'une seule fois le fichier de texte, en appliquant l'ensemble des commandes d'édition à chaque ligne. Comme une seule ligne à la fois est présente en mémoire, sed peut traiter des fichiers de taille complètement arbitraire.

Principe de fonctionnement[modifier | modifier le code]

Le jeu de commandes de sed est basé sur celui de l'éditeur ed. En effet, la majorité des commandes fonctionne de manière similaire, malgré l'inversion du paradigme. Par exemple, la commande 25d signifie s'il s'agit de la ligne 25, alors efface-la (c'est-à-dire, ne la renvoie pas vers la sortie), au lieu de va à la ligne 25 et efface-la, telle que ed l'exécute. Les exceptions notables sont les commandes de copie et de déplacement, qui s'appliquent sur un intervalle de lignes, et qui par conséquent n'ont pas d'équivalent direct dans sed. À la place, sed introduit une mémoire tampon supplémentaire appelé hold space, ainsi que des commandes pour la manipuler.

Par exemple, la commande ed pour copier la ligne 25 à la ligne 76 (25t76) pourrait être codée en deux commandes distinctes dans sed (25h;76g). La première mémorise la ligne dans le hold space, la seconde la récupère lorsqu'il est temps.

Utilisation[modifier | modifier le code]

L'exemple suivant montre une utilisation habituelle de sed :

sed -e 's/Ancien/Nouveau/g' nomFichierEntrée > nomFichierSortie

La commande s signifie substitute (« substituer »). Le drapeau g signifie global, ce qui indique que toutes les occurrences dans chaque ligne doivent être remplacées. Après le premier caractère / est donnée une expression rationnelle que sed doit trouver. Après le deuxième / est précisée l'expression remplaçant ce qu'il a trouvé. La commande de substitution (s///) est de loin la commande de sed la plus puissante et la plus fréquemment utilisée.[réf. nécessaire]

Une application possible de la substitution est la correction d'une faute d'orthographe récurrente, ou le remplacement de toutes les occurrences d'un sigle. Par exemple :

sed -e 's/ficheir/fichier/g' sed.wikipedia > sed.wikipedia.correct
sed -e 's/WP/Wikipedia/g' sed.wikipedia > sed.wikipedia.correct

Il n'est pas obligatoire d'utiliser « / » comme délimiteur. Les caractères « # , - . » (liste non exhaustive) peuvent également servir pour éviter l'accumulation d'anti-slash de « protection » rendant la syntaxe peu lisible. Les commandes suivantes sont équivalentes :

s/\/un\/chemin\/vers/\/une\/autre\/chaine/
s#/un/chemin/vers#/une/autre/chaine#

sed peut aussi servir à numéroter les lignes d'un fichier, supprimer les balises HTML d'un texte, etc. Toutefois, sur certaines plates-formes, le langage Perl est bien souvent utilisé en remplacement de sed.

Sur Unix, sed est souvent utilisé comme filtre dans un tube :

production_de_données | sed -e 's/x/y/'

Dans cet exemple, des données sont générées, puis elles sont modifiées à la volée en remplaçant la première occurrence de x par un y. Pour un remplacement de toutes les occurrences de x la syntaxe à utiliser est :

production_de_données | sed -e 's/x/y/g'


Plusieurs substitutions, ou autres commandes, peuvent être regroupées dans un fichier, appelé script sed (subst.sed dans l'exemple suivant), puis appliquées sur les données :

sed -f subst.sed nomFichierEntrée > nomFichierSortie

En plus des substitutions, d'autres types de traitements simples sont disponibles. Par exemple, le script suivant retire les lignes vides ou qui ne contiennent que des espaces :

sed -e '/^ *$/d' nomFichierEntrée 

Cet exemple utilise des métacaractères pour former des expressions rationnelles :

Méta-caractère Correspondance
^ correspond au début d'une ligne (juste avant le premier caractère)
$ correspond à la fin d'une ligne (juste après le dernier caractère)
. correspond à n'importe quel caractère unique
* correspond à aucune ou plusieurs occurrences du caractère qui précède
[ ] correspond à n'importe lequel des caractères cités entre les crochets

sed permet également l'utilisation des champs pour identifier certaines parties d'une chaîne de caractères. Un champ est défini par une expression rationnelle identifiée par les balises \( et \), le champ peut ensuite être utilisé avec \nn est le numéro du champ (le nombre de champs est limité à 9). Exemple : permuter deux champs séparés par un tiret :

s/\(.*\)-\(.*\)/\2-\1/

Autre exemple : afficher les N derniers caractères d'une chaîne :

s/\(.*\)\(.\{N\}\)/\2/

Deux champs sont définis : \1 qui contiendra les premiers caractères et \2 qui contiendra les N derniers. Les accolades de l'expression rationnelle qui permettent de spécifier le nombre d'occurrences {N} doivent être protégées par un anti-slash.

Programmation[modifier | modifier le code]

Les structures complexes sont possibles avec sed, dans la mesure où il peut être assimilé à un langage de programmation très spécialisé mais simple. Par exemple, le contrôle du fil d'exécution peut être géré à l'aide d'étiquettes (labels, un : suivi du nom de l'étiquette) et de l'instruction de branchement b. Une instruction b suivie d'un nom d'étiquette valide transférera le fil d'exécution au bloc suivant l'étiquette. Si l'étiquette n'existe pas, alors l'instruction termine le script.

sed est l'une des commandes Unix les plus anciennes permettant à la ligne de commande de traiter des fichiers de données. Il a naturellement évolué comme successeur de la célèbre commande grep. Cousin du plus jeune Awk, sed permet au script shell d'effectuer des traitements puissants et très utiles. sed a probablement été l'un des tout premiers outils d'Unix à réellement encourager l'utilisation omniprésente des expressions régulières. En ce qui concerne la vitesse de traitement, sed est généralement plus rapide que Perl, et sensiblement plus rapide que Awk.

sed et Awk sont souvent cités comme étant les ancêtres et les inspirateurs de Perl. En particulier, la syntaxe s/// de l'exemple précédent fait partie intégrante de la syntaxe de Perl.

Le langage de sed ne dispose pas de variable et ne possède qu'un goto primitif comme instruction de contrôle de flux. Toutefois, il est turing-complet[1].

Extensions[modifier | modifier le code]

GNU sed intègre plusieurs nouvelles fonctionnalités telles que l'édition « en place » (le fichier original est remplacé par le résultat du traitement par sed). L'édition en-place est souvent utilisée pour remplacer un script ed. Par exemple :

$ cat oumina.txt
ali  all  albachmohandiss  alaska  alahoma  allo alala  talbidot  taligh
$ sed -i 's/al/d/g' oumina.txt
$ cat oumina.txt
di dl dbachmohandiss daska dahoma dlo dda tdbidot tdigh

peut être utilisé à la place de

$ ed oumina.txt
1,$ s/al/d/g
w
q

Il existe une version améliorée de sed, appelée super-sed (ssed [1]), qui intègre des expressions rationnelles compatibles avec Perl.

Exemple[modifier | modifier le code]

L'exemple qui suit montre comment sed, qui traite habituellement chaque ligne séparément, peut supprimer les sauts de lignes des lignes dont la ligne qui suit commence par une espace.

Pour illustrer l'effet souhaité, considérons le texte suivant :

This is my cat
 my cat's name is betty
This is my dog
 my dog's name is frank

La commande sed donnera :

This is my cat my cat's name is betty
This is my dog my dog's name is frank

Voici la commande :

sed 'N;s/\n / /g;P;D;'

qui peut se décomposer de la manière suivante (les ; permettent de séparer les commandes) :

N;s/\n / /g;P;D;
 
N                  lit (aussi) la ligne suivante
  s/\n / /g         effectue la substitution...
   /\n /                ... d'un saut de ligne suivi d'une espace...
       / /              ... par une simple espace...
          g             ... pour toutes les occurrences
            P       retourne le résultat du traitement
              D     efface ce qui reste afin de ne pas afficher
                        la ligne suivante deux fois 

De façon plus concrète on peut regrouper les entêtes d'un fichier type mbox (par exemple), en le déroulant et supprimant les corps :

#fichier nommé headers.sed
#commande sed -nf headers.sed /var/mail/my_mbox
:start                                #etiquette start
/^From /{                             #adresse "^From "
        N;                            #ajouter une ligne au motif courant
        s/\n\(\t\| \)//;
        /.*\n$/{                      #aux adresses \n$
                        p             #afficher le motif courant
                        b end         #branchement sur end
                }
        b start                       #branchement sur start
}
:end                                  #étiquette end

Voir aussi[modifier | modifier le code]

Articles connexes[modifier | modifier le code]

Références[modifier | modifier le code]

Liens externes[modifier | modifier le code]