Sed
Sed (pour Stream EDitor) est un outil permettant de faire un traitement ligne par ligne d’un flux (pipe) ou d’un fichier.
Quelques petits exemples
| Substitution (la partie gauche du s/// étant une regex) | sed s/bruno/Bruno/ <fichier> > <fichier.nouveau> |
|---|---|
| Suprimer les lignes 10,14, et 16 à 20 d’un fichier | sed ‘10d;14d;16,20d;’ <fichier> > <fichier.nouveau> |
| Supprimer les lignes commençant par ; | sed ‘/^;/d’ <fichier> > <fichier.nouveau> |
| Afficher uniquement les lignes 10 à 15 d’un fichier | sed -n ‘10,15p’ <fichier> > <fichier.nouveau> |
| Afficher uniquement les lignes paires | sed ‘1~2d’ < <fichier> |
généralités
- sed -e expression : applique l’expression au flux d’entrée
- sed -ne expression : idem, mais n’affiche rien en sortie, sauf si on le précise avec p
- sed -i suf -e expression fichier : applique l’expression au fichier (pas besoin de préciser entrée sortie) avec backup de l’ancienne version du fichier en fichier.suf (mettre une chaîne vide à la place de suf pour ne pas avoir de backup)
Attention, l’option -i n’est pas standard, et quand elle existe, elle peut avoir des comportements différents: avec GNU sed, le suffixe est optionnel, alors qu’avec le sed de BSD, il est obligatoire (si bien que dans -i -n, le -n est considéré comme un suffixe et non comme une option).
expression est en général de la forme
- n commande : applique la commande à la ligne n
- n,m commande : applique la commande aux lignes de n à m
- /pattern/ commande : applique la commande aux lignes qui vérifient le pattern
- /pattern/,/pattern2/ commande : applique la commande aux lignes qui se trouvent entre une ligne qui vérifie pattern et une autre qui vérifie pattern2
Commandes
- = : affiche le n° de la ligne
- a : ajoute des lignes, par exemple :
sed -e '/pattern/a\ ajout d'une ligne\ et d'une autre.' < fichier_src > fichier_dest
- c : change des lignes complètes, ex (vire le corps des fonctions, blocs compris entre accolades ouvrantes/fermantes qui débutent une ligne et remplace par “[... corps de la fonction ...]”
sed -e '/^{/,/^}/c\
[... corps de la fonction ...]' < fichier.c > resume
- d : efface la ligne (rmq, “!d” est souvent utilisé pour sélectionner des lignes à garder) et retourne au début du script ou de l’expression avec la ligne suivante du fichier d’entrée.
- D : efface le début du buffer jusqu’au premier \n et repart au début du script (avec une nouvelle ligne si le patternspace a été vidé complètement).
- i : insère avant la ligne.
- l : idem p avec les caractères de contrôle
- n : passe à la ligne suivante (sans appliquer les commandes suivantes à la ligne courante) et y applique la commande suivante.
- N : ajoute la ligne d’entrée suivante au patternspace et passe à la commande suivante.
- s/motif/remplacement/opt
- p : affiche la ligne
- P : affiche le début du patternspace jusqu’au premier \n.
- y/car_src/car_dest/ : substitue des caractères par d’autres
cas du rechercher/remplacer
s/search/replace/opt où opt peut être
- rien : la 1re occurence est remplacée
- g : toutes les occurences sont remplacées
- N : seule la Nième occurence est remplacée
- p : affiche la ligne si subtitution
- w fichier : envoie le résultat de la substitution dans un fichier
- I : insensible à la casse (extension GNU)
Caractères particulier pour le remplacement :
- \i ième référence arrière
- & chaine complète qui correspond au pattern
Syntaxe des Regex
Echappement des caractères
- tous les caractères sauf ‘.‘, ‘*’ et ‘[’ doivent être “échappés” pour prendre leur signification particulière, par exemple écrire ‘a\{3\}’ pour “trois caractères ‘a’ consécutifs et ‘a\+’ pour “un ou plusieurs ‘a’” (mais ‘a*’ pour “0, 1 ou plusieurs ‘a’“). Vaut également pour les parentèses capturantes qui doivent s’utiliser avec \ : ‘\(pattern_a_memoriser\)’
- pour ‘.’, ‘*’ et ‘[’, il faut les échapper pour qu’ils soient pris comme des caractères.
- les caractères \n \t etc. ont bien la signification habituelle de retour chariot et tabulation (dans un shell, attention à mettre les expressions sed entre simples quotes pour que le \n soit bien interprêté par sed et pas par le shell).
- lorsque ‘/’ est utilisé comme délimiteur, mettre ‘\/’ pour qu’il soit lu comme caractère.
- à l’intérieur des crochets, un ‘\’ est toujours un caractère. Pour rechercher le caractère ‘]’, le mettre en premier de la liste, et pour rechercher le caractère ‘-’, le mettre en premier ou en dernier.
Pour aller plus loin
Dès que la liste des commandes excède 2 ou 3 instructions, il est plus simple de faire un script à part. Ex:
- plutôt que
sed -e ‘exp1; exp2;exp3;exp4;’ <fichiercréer un script.sed avec
#!/bin/sed -f exp1 # un peu de commentaires ça fait pas de mal exp2 exp3 exp4
que l’on appelle avec script.sed fichier
- et pour utiliser le -n comme avec
sed -ne ‘exp1; exp2;exp3;exp4;’ <fichierremplace le shebang par#! /bin/sed -nf
Il est aussi possible d’utiliser le “holdspace” (un buffer secondaire).
- P affiche la première ligne du pattern space.
- x échange les contenus du pattern space et du hold space.
- g remplace le contenu du pattern space par celui du hold space.
- G ajoute un caractère nouvelle ligne et le contenu du hold space au pattern space.
- h remplace le contenu du hold space par celui du pattern space.
- H ajoute un caractère nouvelle ligne et le contenu du pattern space au hold space.
- N ajoute un caractère nouvelle ligne et une nouvelle ligne de données au pattern space (s’il n’y a plus de données à lire, l’emploi de cette commande cause la fin du programme).
Plus d’infos sur http://okki666.free.fr/docmaster/articles/linux130.html



