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;’ <fichier cré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;’ <fichier remplace 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

 

Commentaires

filtres/sed.txt · Dernière modification: 2008/01/28 11:02 par danielcaillibaud