Table des matières
http://www.shellunix.com/sed.html sed est un éditeur non interactif.
Cette commande permet d'appliquer un certain nombre de commandes sur un fichier puis d'en afficher le resultat (sans modification du fichier de départ) sur la sortie standard.
sed [-n] [-e commande] [-f fichier de commandes] [fichier]
Pour chaque ligne , on applique la commande (si cela est possible) puis on affiche sur la sortie standard la ligne modifiée ou non.
la syntaxe générale des commandes est de la forme caracterisation_des_adresses commandes avec caractérisation_des_adresses de la forme :
syntaxe : ad1,ad2s/RE/remplacement/flags
Remplace les expressions regulières RE par la chaine de remplacement entre les lignes ad1 à ad2
flags g global, c'est à dire toutes les occurences de la chaine RE (par defaut seule la première occurence est remplacée) p imprime la ligne (utile avec l'option -n) w fichier ecrit la ligne dans le fichier specifié en plus de la sortie standard.
exemple :
sed "s/[Cc]omputer/COMPUTER/g" fichier sed -e "s/\([0-9][0-9]*\)/**\1**/" fichier : encadre le premier nombre de la ligne avec des **
syntaxe : ad1,ad2 !fonction argument
La fonction est appliquée à toutes les lignes qui ne correspondent pas à la caractérisation . La commande de supression d efface les lignes (au niveau de la sortie, le fichier d'origine n'est pas modifié) example:
sed "1,10d" fichier : sortie du fichier à partir de la onzième ligne sed "/^From/!d" fichier : On n'efface tout sauf les lignes commençant par From , donc on imprime les lignes commençant par From.
Remarque : Il est parfois plus facile de caractériser la négation de ce que l'on veut (voir example précédent) . Par exemple plutot de récuperer ce que je veux, j'efface ce qui ne m'interresse pas.
a\texte : écrit le texte après la ligne
i\texte : écrit le texte avant la ligne
exemple :
fichier de commandes :
1i\ \ ------------------------------------------------------------------------------------\ LOGIN USER\ ------------------------------------------------------------------------------------ s/:/!/ s/:/-/ s/:/-/ s/:/!/ s/!.*!/ / s/:.*//
sed -f fich_commandes /etc/passwd resultat :
------------------------------------------------------------------------------------ LOGIN USER ------------------------------------------------------------------------------------ root Operator jd Jean Dupond vm Vincent Martin
exemple : fichier d'entrée :
Un, deux. Trois, quatre.
sed -e "q" fichier resultat : Un, sed -e "/\./=/" -e "/[A-Z]/w capitale" fichier résultat à l'écran : Un, 2 deux. Trois, 4 quatre. résultat dans le fichier capitale : Un, Trois,
nième occurence
$ echo "azerty azerty azerty" | sed 's/az/qw/' qwerty azerty azerty
$ echo "azerty azerty azerty" | sed 's/az/qw/2' azerty qwerty azerty
$ echo "azerty azerty azerty" | sed 's/az/qw/3' azerty azerty qwerty
$ echo "azerty azerty azerty" | sed 's/az/qw/g' qwerty qwerty qwerty
sed ' :s # étiquette N # on ajoute la ligne suivante s/\n/ / # on substitue les fins de lignes par un espace b s # on se branche à l'étiquette ' <example> Sur une ligne : <example> sed ':s;N;s/\n/ /;bs'
sed -n '/foo/,/bar/{//d;p}' fichier sed -n '/Mandriva/,/RedHat/{//d;p}' adresses.txt
$ echo "azerty azerty azerty" | sed 's/a.*z/qw/' qwerty
$ echo "azerty azerty azerty" | sed 's/a[^a]*z/qw/' qwerty azerty azerty
Localiser une ligne par un motif (/222/), charger la ligne suivante dans l'espace de travail et substituer la 2ème occurrence du chiffre "3" par un "4" :
$ echo -e "111\n222\n333\n444" | sed '/222/{n; s/3/4/2}' 111 222 343 444
En n'affichant que la ligne concernée sur la sortie standard :
$ echo -e "111\n222\n333\n444" | sed -n '/222/{n; s/3/4/2p}' 343
Le même avec des lettres :
$ echo -e "AAA\nBBB\nCCC\nDDD" | sed '/BBB/ {n;s/C/Z/2}' AAA BBB CZC DDD
$ echo -e "AAA\nBBB\nCCC\nDDD" | sedsed -i '/BBB/ {n;s/C/Z/2}' /BBB/ { # On sélectionne la ligne avec ce motif n # On place la ligne suivante dans l'espace de travail s/C/Z/2 # On remplace le 2nd C par un Z }
Il va de soit que ces 2 exemples ne sont là que pour une simple démonstration et ne sont pas du tout optimisés ni adaptés en ce qui concerne les substitutions, qui auraient pu (du) être faites en ciblant directement la ligne concernée. Inverser 2 lignes
sed ' 6 { # sélection de la ligne h # copie dans la mémoire annexe N # ajout dans la mémoire principale de la ligne suivante G # ajout du contenu de la mémoire annexe à la mémoire principale #+ la mémoire principale contenant à ce moment là : #++ Ligne n° 6\nLigne n°7\nLigne n° 6\n D # effacement jusqu'au 1er caractère de fin de ligne (\n) } '
Sur une ligne :
sed '6 {h;N;G;D}'
#! /bin/sed -f 1 h # chargement 1ère ligne mémoire secondaire 1 d # effacement 1ère ligne 5 { # sélectionner sur la ligne 5 G # ajouter le contenu de la mémoire secondaire à la mémoire principale N # ajouter la ligne suivante (la 6) s/\n/ /g # substituer tous les sauts de ligne (\n) par un espace }
Sur une seule ligne :
sed -n '1 h; 1 d; 5 { G; N; s/\n/ /g};P' fich.txt
Passer toutes les lignes de commentaires se trouvant sur la même ligne que la commande associée, sur une ligne seule au-dessus de la commande
sed ' /^#\|^$/! { # Exclure les lignes débutant par un dièse et les lignes vides /#/ { # Si la ligne contient un dièse h # La copier dans l'espace annexe. L'original est encore dans l'espace de travail s/.*\(#.*\)/\1/ # Ne conserver que ce qui se trouve après le dièse (dièse compris) x # Échanger l'espace de travail avec l'espace annexe s/\(.*\)#.*/\1/ # Ne conserver que ce qui se trouve avant le dièse x # Échanger l'espace de travail avec l'espace annexe G # Ajouter le contenu de l'espace annexe à l'espace de travail } } ' prog.sed
Sur une seule ligne :
sed '/^#\|^$/!{/#/{h; s/.*\(#.*\)/\1/;x;s/\(.*\)#.*/\1/;x;G;}};' prog.sed
Affichage conditionné
Afficher une ligne de commentaire uniquement si la ligne précédente est vide
sed -n ' /^$/ { n /^#/p } ' fich2.txt
Sur une seule ligne :
sed -n '/^$/{n;/^#/p}' fich2.txt
#!/bin/sh # Émulation de grep -A3 -B5 "motif" fichier # Largement inspiré du script grep4.sh # sur le site : http://www.grymoire.com/Unix/Sed.html#uh-56 case "$#" in 1) ;; *) echo "Usage: $0 \motif\" < fichier";exit;; esac; sed -n ' '/$1/' !{ # Motif non satisfait - ajouter la ligne dans la mémoire annexe H # Remettez-le dans la mémoire principale (espace de travail) x # Ne conserver que 3 lignes dans le tampon # 2 lignes correspondent à .*\n.* # 3 lignes à .*\n.*\n.* # On efface les lignes excédentaires s/^.*\n\(.*\n.*\n.*\)$/\1/ # Mettre les 3 lignes (au plus) dans la mémoire annexe à nouveau x } '/$1/' { # Le motif est satisfait - Ajouter le contenu de la mémoire principale # à la mémoire secondaire H # Prendre la ligne suivante (n) et ajouter les 4 autres (N) n;N;N;N;N # Ajouter le tout à la mémoire annexe H # Échanger le tout avec la mémoire principale x # Afficher les lignes p }'
Sur une seule ligne :
sed -n '/ERROR/! {H;x;s/^.*\n\(.*\n.*\n.*\)$/\1/;x;}; /ERROR/ {H;n;N;N;N;N;H;x;p}'
Voici 2 manières de faire pour émuler "grep -A1 -B1" (juste afficher la ligne précédente et la ligne suivante d'une ligne contenant un motif), en utilisant dans un 1er temps juste un échange entre les 2 mémoires tampons avec la commande "x" et dans un 2nd temps l'emploi de copie et d'ajout avec les commandes "h" et "H" combinées à la commande "x".
#! /bin/bash sed -n ' # affichage sur demande uniquement /indice7/! { # motif absent x # on place la ligne dans la mémoire annexe (en fait on échange le contenu) d # on efface l'espace de travail } /indice7/ { # motif présent x # on l'échange avec le contenu de la mémoire annexe qui contient la ligne précédente p # on l'affiche x # on échange à nouveau la contenu des 2 mémoires p # on affiche la ligne contenant le motif n # on charge la ligne suivante p # on l'affiche x # on la replace dans la mémoire annexe } ' fich3.txt
Sur une seule ligne :
sed -n '/indice7/! {x;d;}; /indice7/{x;p;x;p;n;p;x;}' fich3.txt
#! /bin/bash sed -n ' # affichage sur demande uniquement /indice7/! { # motif absent h # on garde la ligne dans la mémoire annexe } /indice7/{ # motif présent H # on l'ajoute au contenu de la mémoire annexe n # on charge la ligne suivante H # on l'ajoute au contenu de la mémoire annexe x # on échange le contenu des 2 mémoires p # on l'affiche } ' fich3.txt
Sur une seule ligne :
sed -n '/indice7/! {h;}; /indice7/{H;n;H;x;p;}' fich3.txt
Soit le fichier suivant (fich3.txt) : Regrouper sur une seule et même ligne, la ligne contenant "motif" et les lignes suivantes ne comportant pas ce motif.
#! /bin/sed -f :notag # étiquette "pas de motif" /tag/!{ # si la ligne ne contient pas le motif 1!H # ajouter le contenu à la mémoire annexe, sauf la 1ère ligne 1h # copie la 1ère ligne dans la mémoire annexe x # échanger le contenu des 2 mémoires tampons s/\n/ /g # supprimer tous les caractères de nouvelle ligne (\n) x # échanger à nouveau le contenu des 2 mémoires tampons $b lastline # se brancher à l'étiquette "dernière ligne" d # effacer le contenu de l'espace de travail } /tag/{ # si la ligne contient le motif x # échanger le contenu des 2 mémoires tampons /^$/!p # si la ligne n'est pas vide, l'afficher $b lastline # se brancher à l'étiquette "dernière ligne" d # effacer le contenu de l'espace de travail b notag # se brancher à l'étiquette "pas de motif" } :lastline # étiquette "dernière ligne" x # échanger le contenu des 2 mémoires tampons p # afficher le contenu de l'espace de travail
Sur une seule ligne :
sed -n ':notag;/tag/!{1!H;1h;x;s/\n/ /g;x;$b lastline;d;};/tag/{x;/^$/!p;$b lastline;d;b notag;};:lastline;x;p;'
Le fichier de référence : plop
Pattern blablabla blablabla blu ToDelete << Ligne à effacer ToDelete << Ligne à effacer Pattern blablabla blablabla blo ToDelete << Ligne à effacer ToDelete << Ligne à effacer Pattern blablabla blablabla bly ToDelete << Ligne à effacer ToDelete << Ligne à effacer Pattern blablabla blablabla
La commande :
sed ' /Pattern/ !{ # La ligne ne contient pas le motif :z # Étiquette h # On copie l'espace de travail dans la #+ dans la mémoire annexe N # On ajoute la ligne suivante /Pattern$/ !b z # L'espace de travail ne se termine pas par #+ le motif recherché #++ alors on se branche à l'étiquette s/.*\n// # La ligne se termine par le motif, on #+ supprime tout jusqu'au dernier caractère #++ représentant un saut de ligne x # On échange le contenu des 2 mémoires s/\(.*\)\n.*\n.*$/\1/ # On efface les 2 dernières lignes G # On ajoute le contenu de la mémoire annexe #+ à l'espace de travail }' plop
seq 10 | # on génère 10 lignes à partir de la commande "seq" sed -n ' # affichage sur demande uniquement :s # étiquette 1,3 { # tant qu'on n'a pas 3 lignes dans l'espace de travail N # on ajoute la ligne suivante b s # on se branche à l'étiquette jusqu'à remplir la condition } 4,$ { # tant qu'on n'a pas atteint la dernière ligne N # on ajoute la ligne suivante P # on affiche la ligne contenue dans l'espace de travail jusqu'au 1er caractère #+ symbolisant une fin de ligne (\n) D # puis on l'efface de l'espace de travail } '
Sur une seule ligne :
seq 10 | sed -n ':s;1,3{N;bs};4,${N;P;D}'
#!/bin/sed -nf # Hormis la 1ère ligne 1!G # A jouter le contenu de la mémoire annexe à l'espace de travail # Si la dernière ligne est atteinte $p # Afficher le résultat # Copier le contenu de l'espace de travail dans la mémoire annexe h
Sur une seule ligne :
sed -n '1! G;$ p;h'
sed -e ' :boucle # étiquette N # on ajoute la ligne suivante $! b boucle # tant que la dernière ligne n'est pas atteinte #+ on se branche à l'étiquette s/\n/--/g # on substitue toutes les fins de ligne par 2 tirets (--) ' fich.txt
Sur une seule ligne :
sed -e ':boucle;N;$! b boucle; s/\n/--/g'
(si une substitution a été opérée, alors on boucle)
sed -e ' :boucle # étiquette s/^.\{1,20\}$/ & / # on substitue le contenu de la ligne par lui même (&) en ajoutant #+ un espace avant et après t boucle # tant qu'une substitution a eu lieu, se brancher à l'étiquette ' fich.txt
# Sur une seule ligne : #
sed -e ':boucle;s/^.\{1,20\}$/ & /; t boucle'
Transformer "AABBCCDDEEFF" en "AA:BB:CC:DD:EE:FF"
On serait tenté d'utiliser un simple :
echo "AABBCCDDEEFF" | sed 's/../&:/g' |
Mais le problème c'est que cette syntaxe rajoute aussi un ":" en fin de ligne :
AA:BB:CC:DD:EE:FF:
La solution consiste donc à faire une boucle en utilisant la syntaxe des expressions régulières et notamment les limites de caractère ou de mot (word boundary) :
echo "AABBCCDDEEFF" | sed ':z;s/\<..\B/&:/;tz'
(si une substitution n'a pas été opérée, alors on boucle) Éliminer un intervale de lignes dont le début est représenté par un motif (C) et la fin étant le 3ème "Y".
$ var="A\nY\nB\nY\nC\nY\nD\nY\nE\nY\nF\nG" echo -e "$var" |\ sed ' /C/ { :boucle N s/.*Y.*Y.*Y// T boucle } '
Sur une seule ligne :
sed '/C/{:boucle;N;s/.*Y.*Y.*Y//;T boucle};'
Pour la portabilité utiliser plutôt :
sed ' /C/ { :boucle N s/.*Y.*Y.*Y// t b boucle } '
Sur une seule ligne :
sed -e '/C/{:boucle' -e 'N;s/.*Y.*Y.*Y//;t' -e 'b boucle' -e '}'
# Voir aussi cette discussion dans le forum : http://www.commentcamarche.net/forum/affich 4856842 sed substitution
sed ' # recherche le motif /* ... */ s!/\*.*\*/!! # sur une ligne /;[ ]*\/\*/ { # sur plusieurs lignes mais ne commençant pas en début de ligne (après #+ un point virgule suivi éventuellement d'un (ou plusieurs) espace(s) :z # étiquette pour boucler N # on ajoute la ligne suivante s!/\*.*\*/!! # on suprime tout entre /* et */ T z # on teste si une substitution a eu lieu. Dans le cas contraire on boucle } /\/\*/,/\*\// d # sur plusieurs lignes '
Substitution des 2 premières occurrences d'une expression en employant les tampons
echo $A 2007:10:07 16:34:05
echo $A | sed -e ' h # on copie l'espace de travail dans la mémoire annexe s/\(.*\) .*/\1/ # on ne garde que la 1ère partie de l'expression (la date) s/:/-/g # on substitue tous les deux points par des tirets x # on échange le contenu des 2 mémoires s/.*\( .*\)/\1/ # on ne garde que la 2nd partie de l'expression (l'heure) H # on l'ajoute au contenu de la mémoire annexe g # on copie le contenu de la mémoire annexe dans l'espace de travail s/\n// # on supprime le caractère fin de ligne '
Sur une seule ligne :
echo $A |sed -e 'h;s/\(.*\) .*/\1/;s/:/-/g;x;s/.*\( .*\)/\1/;H;g;s/\n//'
Soit un fichier de configuration avec ses directives, ses lignes de commentaires et ses instructions commentées. Chaque paragraphe étant séparé du suivant par une ligne vide. Comment décommenter un jeu d'instructions qui commence par une ligne commentée (contenant un mot-clé) suivie par les directives commentées elles aussi.
sed ' /# mot-clé/ { # motif recherché :label # étiquette /^$/q # si la ligne est vide on quitte n # on charge dans l'espace de travail la ligne suivante s/^#// # on supprime le dièse en début de ligne t label # si une substitution a eu lieu, on se branche à l'étiquette } ' fichier
Sur une seule ligne :
sed '/# mot-clé/{:label;/^$/q;n;s/^#//;t label;}'
Convertir seulement les 12 premiers caractères accentués de chaque ligne :
$ cat plop àaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié ÀaéeÈeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié àaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié àaéeèeÔoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié àaÉeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié
sed ' h # on copie l'espace de travail dans la mémoire annexe s/\(^.\{12\}\).*/\1/ # on récupère les 12 premiers caractères de l'espace de travail y/àâéèêëîïôöùûü/aaeeeeiioouuu/ # on convertit les minuscules y/ÀÂÉÈÊËÎÏÔÖÙÛÜ/AAEEEEIIOOUUU/ # on convertit les majuscules x # on échange le contenu des 2 mémoires s/^.\{12\}\(.*\)/\1/ # on récupère tous les caractères après le 12 ème x # on échange le contenu des 2 mémoires G # on ajoute le contenu de la mémoire annexe s/\n// # on supprime les caractères fin de ligne ' plop
Voici un exemple illustrant avec 2 méthodes bien différentes, la mise en forme d'un texte selon les critères suivants : à partir de la 6ème virgule, supprimer chaque guillemet encadrant chaque champ, exepté le dernier
Le texte de référence
$ cat plop {"88","6","Trademark2","Model6","6OD","7","false","null","null","1","30","1","40","1","60","1","65","1","65","1","70","1","70","1","70"}, {"89","6","Trademark2","Model6","6PD","7","false","null","null","10","30","10","50","10","70","15","75","25","75","25","80","25","80","25","80"},
Méthode avec une boucle conditionnée :
sed ' s/,/,\n/5 # On substitue la 5 ème virgule par elle même #+ suivie d'un saut de ligne :s # étiquette s/\(\n.*\)"/\1/ # là on joue sur la gourmandise des regex, la #+ sous-expression englobant tout ce qui se trouve #++ avant le dernier guillemet que l'on remplace donc #+++ par elle même à l'exception du guillemet t s # tant qu'une substitution a eu lieu, on boucle s/\n\(.*\)}/"\1"}/ # et pour finir on remplace tout ce qui se trouve #+ après le saut de ligne jusqu'à l'accolade fermante #++ par ce contenu plus un guillemet et une accolade #+++ la virgule finale n'étant pas dans la LHS est #++++ reportée naturellement ' plop
Sur une seule ligne :
sed 's/,/,\n/5;:s;s/\(\n.*\)"/\1/;ts;s/\n\(.*\)}/"\1"}/'
Méthode avec mémoire tampon :
sed ' s/\"/§/12 # on substitue le 12 ème guillemet par un caractère quelconque h # on copie la mémoire principale dans la mémoire annexe s/§.*// # on efface ce caractère et tout qui se trouve après x # on échange le contenu des 2 mémoires s/.*§,// # on efface la partie correspondante à la mémoire annexe s/\"//g # on supprime tous les guillemets x # on échange à nouveau le contenu des 2 mémoires G # on ajoute le contenu de la mémoire annexe à la principale s/\n/,/ # on remplace le saut de ligne séparant les 2 mémoires par #+ une virgule s/}/\"}/ # on rajoute le dernier guillemet ' plop
Sur une seule ligne :
sed -e 'h;s/\"/§/12;s/§.*//;x;s/\"/§/12;s/.*§,//;s/\"//g;x;G;s/\n/,/;s/}/\"}/' plop
Dans le même esprit que précédemment, mais ici il faut remplacer les espaces vides contenus au début du 1er champ (et uniquement dans celui-ci) par des 0 (zéros). 2 méthodes là encore, une avec boucle et une utilisant les mémoires tampons.
Fichier de référence :
$ cat plop 1023 LOGS blabla 12333 LOGS blabla 44 LOGS blabla 2580 LOGS blabla 1458 LOGS blabla 5 LOGS blabla
Méthode avec boucle
sed ' /^ / { # seules les lignes commençant par un espace :boucle # étiquette s/^ [^[:alnum:]]*/&\n/ # on ajoute un saut de ligne après le dernier espace du 1er champ s/\([ ]\?\) \{1\}\n/\10/ # on substitue un espace par lui même suivi d'un 0 (zéro) t boucle # tant qu'une substitution a eu lieu, on boucle } '
Sur une seule ligne :
sed '/^ / {:boucle; s/^ [^[:alnum:]]*/&\n/; s/\([ ]\?\) \{1\}\n/\10/; t boucle}' plop
Méthode avec mémoires tampons
sed ' /^ / { # seules les lignes commençant par un espace s/^ [^[:alnum:]]*/&\n/ # on ajoute un saut de ligne après le dernier espace du 1er champ h # on copie la mémoire principale dans la mémoire annexe s/\n.*$// # on efface de la mémoire principale tout ce qui suit le saut de #+ ligne (saut de ligne compris) s/ /0/g # on substitue tous les espaces par des 0 (zéros) x # on échange le contenu des 2 mémoires s/.*\n// # on efface cette fois ci tout ce qui précède le saut de ligne #+ (saut de ligne compris) x # on échange à nouveau le contenu des 2 mémoires G # on copie le contenu de la mémoire annexe à la suite de la #+ mémoire principale s/\n// # et on supprime le saut de ligne } '
Sur une seule ligne :
sed '/^ / {s/^ [^[:alnum:]]*/&\n/;h;s/\n.*$//;s/ /0/g;x;s/.*\n//;x;G;s/\n//}' plop
echo -e "A\nB\nC\nD\nE\nF\nG" | sed '/B/,/F/ c\DELETED'
Les fichiers de références pour les exemples
Vous trouverez ci-dessous la plupart des fichiers utilsés tout au long de ce document pour illustrer les différents exemples vus, afin de vous permettre de mieux cerner certaines commandes.
cat fich.txt Ligne n° 1 Ligne n° 2 Ligne n° 3 Ligne n° 4 Ligne n° 5 Ligne n° 6 Ligne n° 7 Ligne n° 8 Ligne n° 9 Ligne n° 10
cat fich2.txt Ligne n° 1 Ligne n° 2 # commentaire1 # Ligne n° 3 Ligne n° 4 Ligne n° 5 # La prochaine ligne est vide (6) # commentaire2 # Ligne n° 7, la ligne précédente est vide (6) Ligne n° 8 Ligne n° 9 # La prochaine ligne est vide (11) Ligne n° 11 # La ligne précédente est vide (10) Ligne n° 12 Ligne n° 13 Ligne n° 14
cat fich3.txt Ligne n° 1 tag : indice1 indice2 indice3 Ligne n° 2 tag : Ligne n° 3 tag : Ligne n° 4 tag : indice4 indice5 Ligne n° 5 tag : Ligne n° 6 tag: indice6 Ligne n° 7 tag : Ligne n° 8 tag : indice7 indice8 indice9 indice10 Ligne n° 9 tag : Ligne n° 10 tag :
cat adresses.txt Ubuntu 31000 Toulouse Mandriva 34000 Montpellier SuSE 66000 Perpignan Debian 31130 Balma Gentoo 34500 Béziers Slackware 66100 Collioure Fedora 31400 Muret RedHat 34200 Agde Kaella 66500 Elne
cat signature.txt -- Pour toutes correspondances, veuillez vous adressez à : (substituez "<moderateur>" par le nom du modérateur adéquat) <moderateur>@commentcamarche.com Merci de votre attention. L'équipe CCM
cat prog.sed #! /bin/sed -f 1 h # chargement 1ère ligne mémoire secondaire 1 d # effacement 1ère ligne 5 { # sélectionner sur la ligne 5 G # ajouter le contenu de la mémoire secondaire à la mémoire principale N # ajouter la ligne suivante (la 6) s/\n/ /g # substituer tous les sauts de ligne (\n) par un espace }
Sur une seule ligne
sed -n '1 h; 1 d; 5 { G; N; s/\n/ /g};P' fich.txt
Espacer en double un fichier
sed G
Espacer en double un fichier qui a déjà des lignes vides. Le fichier de sortie n'aura jamais plus qu'une ligne vide entre les lignes de texte.
sed 'G;G'
défaire le double-espacement (assumons les lignes paires comme étant toujours vides)
sed 'n;d'
espacer en triple un fichier
sed 'G;G'
insérer une ligne vide au-dessus de chaque ligne qui contient "regex"
sed '/regex/{x;p;x;}'
insérer une ligne vide sous chaque ligne qui contient l'expression régulière "regex"
sed '/regex/G'
insérer une ligne vide au-dessus et au-dessous de chaque ligne qui contient "regex"
sed '/regex/{x;p;x;G;}'
numéroter chaque ligne du fichier (appuyé simplement à gauche). L'utilisation d'une tabulation (voir la note sur '\t' à la fin de ce texte) au lieu d'un espace préservera les marges.
sed = nomdefichier | sed 'N;s/\n/\t/'
numéroter chaque ligne d'un fichier (numéro à gauche, appuyé à droite)
sed = nomdefichier | sed 'N; s/^/ /; s/ *\(.\{6,\}\)\n/\1 /'
numéroter chaque ligne d'un fichier, mais afficher le numéro de ligne seulement si la ligne n'est pas vide.
sed '/./=' nomdefichier | sed '/./N; s/\n/ /'
compter les lignes (émulation de "wc -l")
sed -n '$='
sed 's/.$//' assume que toutes les lignes se terminent avec CR/LF sed 's/^M$//' sous bash/tcsh, enfoncer Ctrl-V puis Ctrl-M sed 's/\x0D$//' fonctionne sous ssed, gsed 3.02.80 ou plus récent
sed "s/$/`echo -e \\\r`/" ligne de commande sous ksh sed 's/$'"/`echo \\\r`/" ligne de commande sous bash sed "s/$/`echo \\\r`/" ligne de commande sous zsh sed 's/$/\r/' gsed 3.02.80 ou plus haut
sed "s/$//" méthode 1 sed -n p méthode 2
Peut seulement être utilisé avec UnxUtils sed, version 4.0.7 ou plus récente. La version UnxUtils peut être utilisée avec le modificateur "—text" qui apparaît lorsque vous utiliser le modificateur "—help". Sinon, la conversion des retours de chariot DOS vers la version UNIX ne peut se faire avec SED dans un environnement DOS. Utiliser 'tr' au lieu.
sed "s/\r//" infile >outfile UnxUtils sed v4.0.7 ou plus récent tr -d \r <infile >outfile GNU tr version 1.22 ou plus récent
éliminer tout espace blanc (espaces, tabulations) à la gauche de chaque ligne, et appuyer le résultat à la marge gauche
sed 's/^[ \t]*//' voir note au sujet de '\t' à la fin de ce fichier
éliminer tout espace blanc (espaces, tabulations) à la fin de chaque ligne
sed 's/[ \t]*$//' voir note au sujet de '\t' à la fin de ce fichier
éliminer tout espace blanc des deux bouts de chaque ligne
sed 's/^[ \t]*//;s/[ \t]*$//'
insérer 5 espaces au début de chaque ligne (décalage de page vers la droite)
sed 's/^/ /'
aligner tout le texte à la droite sur la 79e colonne
sed -e :a -e 's/^.\{1,78\}$/ &/;ta' mettre à 78 plus un espace
centrer tout le texte sur le centre de la 79e colonne. Dans la première méthode, tout espace au début de la ligne est significatif, et des espaces sont ajoutés à la fin de la ligne. Dans la deuxième méthode, les espaces précédant les lignes sont ignorés pendant le processus de centrage, et aucun espace n'est ajouté à la fin des lignes.
sed -e :a -e 's/^.\{1,77\}$/ & /;ta' méthode 1 sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/' méthode 2
substituer (trouver et remplacer) "foo" avec "bar" sur chaque ligne
sed 's/foo/bar/' replacer seulement la première instance de la ligne sed 's/foo/bar/4' replacer seulement la quatrième instance de la ligne sed 's/foo/bar/g' replacer toutes les instances de la ligne sed 's/\(.*\)foo\(.*foo\)/\1bar\2/'replacer l'avant-dernier cas sed 's/\(.*\)foo/\1bar/' replacer seulement le dernier cas
substituer "foo" par "bar" SEULEMENT pour les lignes contenant "baz"
sed '/baz/s/foo/bar/g'
substituer "foo" par "bar" A L'EXCEPTION des lignes contenant "baz"
sed '/baz/!s/foo/bar/g'
substituer "scarlet" ou "ruby" ou "puce" par "red"
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g' la plupart des seds gsed 's/scarlet\|ruby\|puce/red/g' GNU sed seulement
renverser l'ordre des lignes (émulation de "tac") bug/boni dans HHsed v1.5 cause l'élimination des lignes vides
sed '1!G;h;$!d' méthode 1 sed -n '1!G;h;$p' méthode 2
renverse l'ordre de chaque caractère sur une ligne (émulation de "rev")
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
joindre des paires de lignes ensemble côte-à-côte (émulation de "paste")
sed '$!N;s/\n/ /'
si une ligne se termine par une barre oblique inversée, joindre la ligne suivante à la présente
sed -e :a -e '/\\$/N; s/\\\n//; ta'
si une ligne débute par le symbole égalité, l'ajouter à la précédente
et remplacer le symbole "" par un espace simple
<pre class
"example">
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
insérer des virgules aux chaînes numériques, changeant "1234567" en "1,234,567"
gsed ':a;s/\B[0-9]\{3\}\>/,&/;ta' GNU sed sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' autres seds
décimaux et signes négatifs (GNU sed)
gsed -r ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta'
ajouter une ligne blanche à chaque cinq lignes (après lignes 5, 10, 15, 20, etc.)
gsed '0~5G' GNU sed seulement sed 'n;n;n;n;G;' autres seds
imprimer les dix premières lignes d'un fichier (émulation de "head")
sed 10q
imprimer la première ligne d'un fichier (émulation "head -1")
sed q
imprimer les dernières dix lignes d'un fichier (émulation "tail")
sed -e :a -e '$q;N;11,$D;ba'
imprimer les dernières deux lignes d'un fichier (émulation "tail -2")
sed '$!N;$!D'
imprimer la dernière ligne d'un fichier (émulation "tail -1")
sed '$!d' méthode 1 sed -n '$p' méthode 2
imprimer l'avant-dernière ligne d'un fichier
sed -e '$!{h;d;}' -e x pour fichiers d'une ligne , imprimer une ligne vide sed -e '1{$q;}' -e '$!{h;d;}' -e x pour fichiers d'une ligne , imprimer la ligne sed -e '1{$d;}' -e '$!{h;d;}' -e x pour fichiers d'une ligne , ne rien imprimer
imprimer seulement les lignes coïncidant avec l'expression régulière regexp (émulation "grep")
sed -n '/regexp/p' méthode 1 sed '/regexp/!d' méthode 2
imprimer seulement les lignes NE coïncidant PAS avec l'expression régulière regexp (émulation "grep -v")
sed -n '/regexp/!p' méthode 1, corresponds avec méthode ci-haut sed '/regexp/d' méthode 2, syntaxe plus simple
imprimer la ligne précédant celle qui coïncide avec regexp, mais pas la ligne coïncidant avec regexp
sed -n '/regexp/{g;1!p;};h'
imprime la ligne suivant celle qui coïncide avec regexp, mais pas la ligne coïncidant avec regexp
sed -n '/regexp/{n;p;}'
imprime une ligne de contexte avant et après regexp, avec numérotation de lignes indiquant l'endroit de coïncidence avec regexp (similaire à "grep -A1 -B1")
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h
grep pour AAA et BBB et CCC (peu importe l'ordre)
sed '/AAA/!d; /BBB/!d; /CCC/!d'
grep pour AAA et BBB et CCC (dans cet ordre)
sed '/AAA.*BBB.*CCC/!d'
grep pour AAA ou BBB ou CCC (émulation "egrep")
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d la plupart des seds gsed '/AAA\|BBB\|CCC/!d' GNU sed seulement
imprime paragraphe si il contient AAA (paragraphes séparés par des lignes vides) HHsed v1.5 veuillez insérer un 'G;' après 'x;' dans les trois commandes ci-bas
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'
imprime le paragraphe s'il contient AAA et BBB et CCC (peu importe l'ordre)
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'
imprime le paragraphe s'il contient AAA ou BBB ou CCC
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d gsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d' GNU sed seulement
imprime seulement les lignes longues de 65 caractères ou plus
sed -n '/^.\{65\}/p'
imprime seulement les lignes longues de moins de 65 caractères
sed -n '/^.\{65\}/!p' méthode 1, correspond à ci-haut sed '/^.\{65\}/d' méthode 2, syntaxe plus simple
imprime la partie du fichier depuis la coïncidence à l'expression régulière, jusqu'à la fin du fichier
sed -n '/regexp/,$p'
imprime la partie du fichier incluse par le numéros de ligne 8-12 inclusivement
sed -n '8,12p' méthode 1 sed '8,12!d' méthode 2
imprime la ligne numéro 52
sed -n '52p' méthode 1 sed '52!d' méthode 2 sed '52q;d' méthode 3, très efficace sur de gros fichiers
commençant avec la troisième ligne, imprimer chaque septième ligne
gsed -n '3~7p' GNU sed seulement sed -n '3,${p;n;n;n;n;n;n;}'autres seds
imprime la partie du fichier contenue entre deux expression régulières incluant celles contenant les expressions régulières
sed -n '/Iowa/,/Montana/p' respecte les hauts de casse
imprime tout le fichier SAUF la section coïncidant avec deux expressions régulières
sed '/Iowa/,/Montana/d'
élimine les lignes consécutives identiques d'un fichier (émulation "uniq"). La première ligne d'un ensemble de lignes identiques consécutives est retenue, les autres éliminées
sed '$!N; /^\(.*\)\n\1$/!P; D'
élimine les lignes en duplicata, non-consécutives, d'un fichier. Prenez garde de ne pas déborder les limites de la mémoire tampon sinon veuillez utiliser le GNU sed.
sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'
éliminer toutes les linges sauf celles en duplicata (émulation "uniq -d").
sed '$!N; s/^\(.*\)\n\1$/\1/; t; D'
éliminer les dix première lignes d'un fichier
sed '1,10d'
écraser la dernière ligne d'un fichier
sed '$d'
écraser les deux dernières lignes d'un fichier
sed 'N;$!P;$!D;$d'
écraser les dix dernières lignes d'un fichier
sed -e :a -e '$d;N;2,10ba' -e 'P;D' méthode 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' méthode 2
écraser chaque huitième ligne
gsed '0~8d' GNU sed seulement sed 'n;n;n;n;n;n;n;d;' autres seds
écraser les lignes coïncidant avec un patron
sed '/patron/d'
écraser TOUTES les lignes vides d'un fichier (émulation "grep '.' ")
sed '/^$/d' méthode 1 sed '/./!d' méthode 2
écraser toutes les lignes vides consécutives (sauf la première); aussi écrase toutes les lignes vides du début et de la fin d'un fichier (émulation "cat -s")
sed '/./,/^$/!d' méthode 1, retient 0 ligne vide au début, 1 à la fin sed '/^$/N;/\n$/D' méthode 2, permet 1 ligne vide au début, 0 à la fin
écraser toutes lignes vides CONSÉCUTIVES d'un fichier, sauf les deux premières
sed '/^$/N;/\n$/N;//D'
écraser toutes les lignes vides au début d'un fichier
sed '/./,$!d'
écraser toutes les lignes vides de la fin d'un fichier
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' fonctionne sur tous les seds sed -e :a -e '/^\n*$/N;/\n$/ba' ibid, sauf pour gsed 3.02.*
écrase la dernière ligne de chaque paragraphe
sed -n '/^$/{p;h;};/./{x;/./p;}'
éliminer les sur-frappes nerf (char, retour) des pages man. La commande 'echo' peut nécessiter le modificateur -e si vous utilisez Unix System V ou du shell bash.
sed "s/.`echo \\\b`//g" double guillemets requis dans l'environnement Unix sed 's/.^H//g' sous bash/tcsh, enfoncer Ctrl-V et ensuite Ctrl-H sed 's/.\x08//g' expression hexadécimale pour sed 1.5, GNU sed, ssed
obtenir l'entête des messages Usenet/courriel
sed '/^$/q' élimine tout ce qui suit la première ligne vide
obtenir le corps des messages Usenet/courriel
sed '1,/^$/d' élimine tout ce qui précède la première ligne vide
obtenir l'entête Sujet, mais élimine la portion initiale "Subject: "
sed '/^Suject: */!d; s///;q'
obtenir l'adresse de retour dans l'entête
sed '/^Reply-To:/q; /^From:/h; /./d;g;q'
parcourir et isoler l'adresse proprement dite. Extirpe l'adresse courriel par elle-même, du script précédent
sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//'
ajouter un crochet et espace à chaque ligne (citer un message)
sed 's/^/> /'
écraser le crochet et espace précédant chaque ligne (enlever la citation du message)
sed 's/^> //'
écraser la plupart des étiquettes HTML (s'accommode des étiquettes multi-lignes)
sed -e :a -e 's/<[^>]*>//g;/</N;//ba'
extrait les parties uuencodées binaires, éliminant les entêtes superflues, de façon à garder seulement la partie uuencodée. Les fichiers doivent être passé à sed dans le bon ordre. La version 1 peut être passée depuis la ligne de commande; la version 2 peut faire partie d'un script de shell Unix. (Modifiée par un script originaire de Rahul Dhesi.)
sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode vers. 1 sed '/^end/,/^begin/d' "$@" | uudecode vers. 2
triage des paragraphes d'un fichier par ordre alphabétique. Les paragraphes sont séparés pour des lignes vides. GNU sed utilise \v comme tabulation verticale, ou n'importe lequel caractère unique peut servir.
sed '/./{H;d;};x;s/\n/={NL}=/g' file | sort | sed '1s/={NL}=//;s/={NL}=/\n/g' gsed '/./{H;d};x;y/\n/\v/' file | sort | sed '1s/\v//;y/\v/\n/'
compresser en zip chaque fichier .TXT individuellement, écrasant le fichier source et assignant le nom du fichier compressé .ZIP au nom de base du fichier source .TXT (sous DOS: le modificateur "dir /b" retourne les noms de base des fichiers tout en majuscules)
echo @echo off >zipup.bat dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat
Sed accepte une ou plusieurs commandes et les applique toutes, de façon séquentielle, à chacune des lignes d'entrée. Une fois que toutes les commandes furent exécutées à la première ligne d'entrée, cette ligne est envoyée vers la sortie, une deuxième ligne est lue comme nouvelle entrée, et le cycle se répète. Les exemples précédents assument que l'entrée provient de l'entrée standard (ex. la console, normalement ce serait l'entrée dans un pipeline). Un ou plusieurs noms de fichiers peuvent être ajoutés à la ligne de commande si l'entrée ne provient pas de l'entrée standard. La sortie est passée à la sortie standard (stdout ou l'écran-témoin). Donc:
cat nomdefichier | sed '10q' utilise entrée pipeline sed '10q' nomdefichier même chose, en moins du cat inutile sed '10q' nomdefichier > nouveaufichier re dirige la sortie vers le disque
incluant comment fournir les instructions sed à partir d'un fichier au lieu de la ligne de commande, veuillez consulter le livre "SED & AWK, 2nd Edition," par Dale Dougherty et Arnold Robbins (O'Reilly, 1997; http://www.ora.com), "UNIX Text Processing," par Dale Dougherty and Tim O'Reilly (Hayden Books, 1987) ou les tutoriels par Mike Arst distribués dans U-SEDIT2.ZIP (plusieurs sites). Afin d'exploiter la pleine puissance de sed, l'usager doit comprendre les 'expressions régulières'. A cette fin, consultez "Mastering Regular Expressions" par Jeffrey Friedl (O'Reilly, 1997). Le manuel UNIX ("man") contient des pages qui pourraient être utiles ("man sed", "man regexp", ou la sous-section sur les expressions régulières ("man ed"), quoique les pages man sont notoires pour leur difficultés. Elles ne furent pas rédigées pour enseigner l'usage de sed ou des expressions régulières, mais comme texte de référence pour ceux qui connaissent déjà ces outils.
Les exemples précédents utilisent les guillemets simples ('...') au lieu des guillemets doubles ("...") pour encadrer ou citer les commandes d'édition, puisque sed est typiquement utilisé sur les systèmes d'exploitation UNIX. Les guillemets simples préviennent le shell UNIX d'interpréter les symbole dollar ($) ainsi que les guillemets renversés (`...`) qui seraient interprétés par le shell s'ils seraient encadrés ou cités par les guillemets doubles. Les usagers du shell "csh" et dérivés doivent aussi citer le point d'exclamation avec l'oblique arrière (\!) si l'on veut que les exemples ci-haut fonctionnent, même avec à l'intérieur de guillemets simples. Les versions de sed écrites pour DOS invariablement requièrent des guillemets doubles ("...") au lieu des guillemets simples utilisés pour citer les commandes d'édition sed.
Afin de clarifier la documentation, nous avons utilisé l'expression '\t' pour indiquer le caractère de tabulation (0x09) dans les scripts. Cependant, la plupart des versions de sed ne reconnaissent pas l'abréviation '\t', donc, lorsque vous écrirez ces directives à l'invite de commande, vous devrez enfoncer la clef TAB au lieu de l'abréviation. '\t' est supporté comme métacharactère d'expression régulière dans awk, perl, et HHsed, sedmod, et GNU sed v3.02.80.
Les version de sed diffèrent entre elles, et de légers écarts de syntaxe se présentent. En particulier, la plupart ne reconnaissent pas l'usage d'étiquettes (:nom) ou ne permettent pas les instructions de branchement (b,t) à l'intérieur des commandes d'édition, sauf à la fin de ces commandes. Nous avons donc utilisé une syntaxe qui serait portable à la majorité des usagers de divers sed, bien que les versions les plus populaires du GNU sed permettent une syntaxe plus élaborée. Lorsque les lecteurs verront une longue chaîne de commande telle celle-ci:
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
ils seront réjouis de savoir que GNU sed leur permettra de réduire le tout en ceci:
sed '/AAA/b;/BBB/b;/CCC/b;d' ou bien encore en ceci: sed '/AAA\|BBB\|CCC/b;d'
En plus, se rappeler que bien que certaines versions de sed acceptent une commande telle "/one/ s/RE1/RE2/", d'autres ne permettent pas ceci: "/one/! s/RE1/RE2/", qui contient un espace avant le 's'. Éviter d'enter l'espace lorsque vous entrez la commande.
Lorsque vous avez besoin de vitesse pour l'exécution de vos scripts (si vos fichiers d'entrée sont volumineux, ou un processeur lent ou un disque dur lent) la substitution sera plus rapide si vous faites un recherche pour la chaîne à être changée avant de faire la substitution "s/.../.../". Voir:
sed 's/foo/bar/g' nomdefichier commande normale de substitution sed '/foo/ s/foo/bar/g' nomdefichier exécution plus rapide sed '/foo/ s//bar/g' nomdefichier raccourci de syntaxe
Si vous devez altérer ou écraser seulement une section d'un fichier et que vous voulez seulement une sortie pour une première partie d'un fichier quelconque, la commande "quit" (q) dans le script réduira considérablement le temps d'exécution pour de gros fichiers. Donc:
sed -n '45,50p' nomdefichier imprimez les lignes nos. 45-50 d'un fichier sed -n '51q;45,50p' nomdefichier ibid, mais bien plus vite
Compilé par Éric Pement [at]northpark[dot]edu version 5.5 Traduit par Gérard Piette gpiette[at]ncf[dot]ca
http://sed.sourceforge.net/sed1line_fr.html
La version récente de ce fichier (en Anglais) se retrouve ici:
Ce fichier aussi disponible dans d'autres langages:
Si vous avez des scripts additionnels à contribuer, ou si vous trouvez des erreurs dans ce document, S.V.P. envoyer un courriel au compilateur du document. Indiquez quelle version de sed vous utilisez, le système d'exploitation en usage et pour laquelle votre sed fut compilé, ainsi que la nature de votre problème. Afin de se qualifier comme un script d'une ligne, la commande doit avoir moins de 65 caractères. Divers scripts dans ce fichiers furent rédigés ou contribués par les bonnes gens suivants: