====== 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/ > | ^ Supprimer les lignes 10,14, et 16 à 20 d'un fichier | sed '10d;14d;16,20d;' > | ^ Supprimer les lignes commençant par ; | sed '/%%^%%;/d' > | ^ Afficher uniquement les lignes 10 à 15 d'un fichier | sed -n '10,15p' > | ^ Afficher uniquement les lignes paires | sed '1~2d' < | ===== 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;' #!/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;'