La plupart des personnes utilisent
sedpour ses fonctionnalités de substitutions de chaînes de caractères. Il est possible, par exemple, grâce au filtre sed de rechercher du texte dans un fichier et de modifier ce dernier. La puissance du filtre sed vient également du fait qu'il est possible d'utiliser des expressions régulières.
Son principe de fonctionnement est le suivant:
Sed lit en entrée les données ligne par ligne (en provenance d'un fichier ou d'ailleur) et modifie ces dernières selon des règles spécifiques entrées par l'utilisateur.
On peut dire que le filtre sed est une sorte d'éditeur de texte non interactif ou editeur de texte en ligne de commande.
I. Syntaxe d'utilisation
La commande sed contient une ou plusieurs commandes d'éditions et éventuellement des options.
sed [OPTIONS] 'commande d'édition' [fichier...]
Le filtre Sed met à dispositions diverses options et commandes d'éditions. Nous verrons dans un premier temps (dans le sous chapitre I.a.) quelles sont les différentes options disponibles, puis dans un deuxième temps (dans le sous chapitre I.b.), nous aborderons les commandes d'éditions.
I.a. Options :
Je ne vous parlerai ici que des options sed les plus couramment utilisées. Vous pourrez éventuellement taper la commande man sed pour avoir une liste d'options plus complète.
-e commande
L'option -e est très utile car elle permet d'utiliser plusieurs commandes d'édition à la suite.
Exemple : sed -e 'commande' -e 'commande'
Exemple : sed -e 'commande' -e 'commande'
-f Fichier_Script
Cette option permet d'ajouter des commandes d'édition se trouvant dans un fichier script. Faire un fichier script est très simple, il suffit de remplir ce dernier avec des commandes d’éditions (chaque ligne doit comporter une commande d'édition différente).
-i[SUFFIXE]
Par défaut sed ne modifie pas directement le fichier qui est fournit en paramètre mais affiche le résultat du traitement sur la sortie standard (stdout). Grâce à cette option sed modifiera directement le fichier fournit en paramètre. On éventuellement mettre un suffixe pour effectuer une sauvegarde du fichier fournit (Exemple de suffixe: -i.bak)
I.b. Commandes d'éditions sed:
Pour éditer le texte sed met a disposition plusieurs commandes d'éditions permettant de spécifier les règles de modification souhaitées. Ces dernières ont une syntaxe d'utilisation particulière que je vais tenter de vous décrire.
La syntaxe d'utilisation des commandes d'éditions sed est la suivante :
[addresse[,addresse]]commande d'édition[arguments]
Comme vous pouvez l'observer, une commande d'édition sed peut être préfixé par une ou deux adresses.
Les adresses :
Les adresses correspondent à des lignes du texte. Il est possible de spécifier les numéros de lignes, par exemple les adresses 5,7 indiqueront à la commande sed d'agir sur les lignes 5 à 7. On peut également utiliser des expressions régulières, par exemple l'adresse /motif/ indiquera à sed de traiter les lignes correspondantes à l'expression régulière motif. Chaque ligne contenant la chaîne de caractères motif sera alors traitée. On peut deux la même façon utiliser deux expressions régulières, par exemple /motif1/,/motif2/ correspond à un domaine de lignes compris entre motif1 et motif2. Nous verrons plus bas comment utiliser les expression régulières.
Maintenant nous allons aborder les commandes d'éditions sed disponibles pour editer le texte. Ces dernières peuvent supporter parfois qu'une seule adresse maximale. D'autres peuvent en supporter deux.
Les commandes d'éditions sed pouvant supporter une adresse :
[adresse]i
q Afficher les n premières lignes.
Cette commande d'édition sed permet d’insérer du texte avant la ligne correspondante à l'adresse. Si aucune adresse n'est spécifiée le texte sera inséré au début.
[adresse]a
Ajoute du texte après la ligne.q Afficher les n premières lignes.
II. Insérer et ajouter du texte
Vous pouvez utiliser la commande i pour insérer du texte avant une ligne et a pour ajouter du texte après une ligne.
Ajouter
Bonjour monsieuraprès la ligne 5
sed '5a\Bonjour monsieur\' fichier.txt
Insérer
Bonjour monsieuravant la ligne 5
sed '5i\Bonjour monsieur\' fichier.txt
III. Substitution
Sed permet de rechercher et remplacer des mots ou des parties de texte, on appelle cela: substituer des chaînes de caractères.Par exemple pour substituer une occurrence par une autre:
Remplacer
romainpar
julien
sed -e 's/romain/julien/' fichier.txt
III.a. Utiliser l'option global g
Sed traite le flux ligne par ligne. Attention, sans l'option g sed ne traitera que la première occurrence trouvé sur la ligne en cours de traitement, c'est à dire que si sur une même ligne, la chaîne de caractères recherchée apparaît plusieurs fois, seulement la première occurrence sera traitée. L'option g permet de traiter toutes les occurrences.
Utilisation de l'option g (global)
sed -e 's/toto/titi/g' fichier.txt
III.b. Utiliser l'option de négation !
Afin d'inverser la fonction sed utilisée, il est possible d'utiliser l'opérateur ! dit de négation.Voici un exemple:
Remplacer
tontonpar
tatisauf à la ligne 5
sed '5!s/tonton/tati/g' fichier.txt
III.c. Agir uniquement sur certaines lignes du fichier
Il possible de dire à sed de ne traiter qu'une partie du fichier texte, pour cela on utiliser une plage d'adresse correspondant aux lignes qu'on souhaite traiter.Voici ci dessous un exemple:
Remplacer
tontonpar
tatiuniquement entre les lignes 5 et 12
sed '5,12s/tonton/tati/g' fichier.txt
III.d. Sélectionner les occurrences
Si jamais il y a plusieurs occurrences d'une même chaîne sur une même ligne, il est possible d'indiquer à sed laquelle on souhaite traiter.Exemple:
Remplacer seulement la deuxième occurrence du mot
téléphonepar le mot
fax
sed 's/telephone/fax/2'
IV. Afficher du texte
L'option p qui a pour signification
Afficher les lignes 18 à 25
sed -n '18,25p' fichier.txt
Il est possible avec sed de sélectionner un paragraphe.
Afficher le paragraphe qui commence par la ligne contenant la chaîne de caractère
prendre la voitureet qui termine par la ligne contenant la chaîne
arriver le soir
sed -n '/prendre la voiture/,/arriver le soir/p' monfichier
V. Effacer du texte
Sed permet grâce à la fonction d (delete) d’effacer des chaînes de caractères.Par exemple, si vous souhaitez éffacer les lignes 18 à 25 d'un fichier, vous pouvez taper la commande suivante:
sed '18,25d' fichier.txt
Si maintenant, vous souhaitez effacer tout sauf les trois premières lignes d'un fichier, vous pouvez taper la commande suivante:
sed '1,3!d' fichier.txt
VI. Les méta-caractères
Les métacaractères sont des caractères typographiques spéciaux qui permettent de créer des expressions rationnelles; ces dernières sont utiles pour rechercher des chaînes de caractères répondant à certain critères.Metacaractère | Description |
. | Désigne un seul caractère quelconque excepté le caractère '\n' (nouvelle ligne). Par exemple: tot. correspond à tota, totb, totc, totd, tote etc... |
^ | Indique le début de la ligne Par exemple: ^root identifie une ligne commençant par root |
$ | Indique la fin d'une ligne Par exemple: mécanisme$ identifie une ligne finissant par mécanisme |
[ ] | Correspond à n'importe quel caractères cités entre les crochets Exemple 1 : [tT]toto correspond aux chaînes de caractères toto et Toto Exemple 2 : [a-z] correspond à l'intervalle de caractères de a jusqu'à z Exemple 3 : [4-9] correspondant à l'intervalle de caractères de 4 à 9 c'est à dire 4,5,6,7,8,9 Exemple 4 : 1[4-9]0 correspondant à 140,150,160,170,180,190 |
VI.a. Exemples d'utilisation des métacaractères avec la commande Sed:
VI.a.1. Exemple d'utilisation du métacaractère .
Remplacer ce qui commence par
totet qui fait 4 caractères par
toto
sed -e "s/tot./toto/g"
Le métacaractére .représente un caractère quelconque.
VI.a.2. Exemple d'utilisation du metacaractère ^
Effacer les lignes débutant par
^root
sed -e "/^root/d"
Modifier les lignes qui débutent par
rooten substituant ce dernier par
user
sed -e "s/^root/user/"
VI.a.3. Exemple d'utilisation du metacaractère $
Supprimer les lignes finissant par la chaîne de caractères
toto
sed "/toto$/d"
Supprimer les lignes vides
sed -e "/^$/d"
Modifier les lignes terminant par
;par le caractère
.
sed -e "s/$;/\./"
VI.a.4. Exemple d'utilisation des metacaractères []
Remplacer les chaînes qui commencent par
totoet qui finissent par un chiffre entre 0 et 9 par la chaîne
tata
sed -e "s/toto[0-9]/tata/g"
Supprimer les caractères
a,
bou
c
sed -e "s/[abc]//g"
VII. Les quantificateurs
Les quantificateurs se place après un caractères et permettent d'exprimer une valeur de répétition ou de nullité.Quantificateurs | Description |
* | Aucun ou plusieurs caractère qui le précède Exemple : toto* correspond à tot, toto, totoo, totooo etc... Remarque: .*Correspond à zéro ou plusieurs caractères quelconques |
? | Zéro ou une occurrence du caractère qui le précède Exemple : toto? correspond à tot ou toto |
+ | Un ou plusieurs caractères qui le précède Exemple : toto+ correspond à toto, toto, totoo, totooo etc... |
VII.a. Exemples d'utilisation des quantificateurs avec Sed:
VII.a.1. Exemple d'utilisation du quantificateur *
Remplacer tout ce qui commence par
totet qui est suivi du caractère
ozéro ou plusieurs fois (c'est à dire: tot, toto, totoo, totooo, totoooo...) par la chaîne
baba
sed -e "s/toto*/toto/g"
Supprimer les chaînes de caractères qui commencent par
toto, qui contiennent n'importe quels caractères et finissent par
baba
sed -e "/^toto.*baba$/d"
VII.a.2. Exemple d'utilisation du quantificateur ?
Remplacer
tatou
tatipar
toto
sed -e "s/tati?/toto/g"
VII.a.2. Exemple d'utilisation du quantificateur +
Remplacer ce qui correspond à
tata,
tataa,
tataaaaetc... par le mot
toto
sed -e "s/tata+/toto/g"
Liens internes
- (fr) man2linux.blogspot.com - Tutoriel de prise en main pour débutant du filtre Sed
- (fr) man2linux.blogspot.com - Sed - Afficher des numeros de lignes
Liens externes
- (fr) shellunix.com - Sed - Documentation succincte
- (fr) commentcamarche.net - Documentation très complete de Sed
- (fr) fr.wikipedia.org - Wikipedia - Stream Editor
- (fr) doc.ubuntu-fr.org - Sed - Documentation Ubuntu francophone
- (fr) gentoo.org - Documentation Gentoo -- Sed par l'exemple — Première partie
- (fr) gentoo.org - Documentation Gentoo -- Sed par l'exemple — Deuxieme partie
- (en) sed.sourceforge.net - Sed Faq
- (en) grymoire.com - Sed - An Introduction and Tutorial
- (fr) siteduzero.com - Tutoriel sur la commande Sed
Ce commentaire a été supprimé par l'auteur.
RépondreSupprimerBonjour oumina el hassane,
RépondreSupprimerJe vais essayer de t'expliquer ce que fait la commande sed que tu as écrite:
Cette commande va ajouter une ligne dans le fichier /etc/squid3/squid.conf
La ligne qui s'ajoute automatiquement est la suivante:
visible_hostname "Nom d'hôte de votre ordinateur"
En tapant:
echo $HOSTNAME
vous pouvez voir le nom d’hôte de votre machine.
Cette ligne va s'ajouter dans le fichier "squid.conf" juste en dessous de la ligne suivante déjà présente:
# visible_hostname
Les étapes Sed se décomposent de la manière suivante:
ETAPE 1:
--------
On peut voir l'utilisation de l'option "-i" (/bin/sed -i) dans ta commande, cela signifie que le fichier est directement modifié.
ETAPE 2:
--------
Ta commande sed peut être décomposée (grâce aux crochets) en deux parties distinctes:
ADRESSE{COMMANDES;}
C'est la première chose importante à remarquer.
Les crochets utilisés dans ta commande Sed permettent de délimités ces deux parties.
ETAPE 3:
--------
La première partie de la commande qui se trouve avant la partie entre crochets "{ }" est la suivante:
/TAG: visible_hostname/,/^#[ ]*visible_hostname/
Cela correspond a une adresse;
Une adresse peut être décomposée en deux autres parties distinctes:
/LIGNE1,/LIGNE2/
Sed va repérer et traiter uniquement la partie textuelle qui se trouve entre les lignes 1 et 2.
ETAPE 4:
--------
La ligne 1 de ta commande est la ligne qui contient la chaîne de caractères suivante:
TAG: visible_hostname
La ligne 2 correspond à l'expression rationnelle suivante:
^#[ ]*visible_hostname
^# correspond à une chaîne de caractères qui commence par #
[ ]* correspond à zéro, un ou plusieurs caractères espaces.
Donc, pour la ligne 2 qui est une expression rationnelle, Sed va rechercher une ligne de texte :
- qui commence par le caractère #
- et qui contient éventuellement un, zéro ou plusieurs caractères espaces.
ETAPE 5:
--------
Maintenant que nous avons délimité la partie dans laquelle le traitement allait être effectuer nous allons nous pencher sur la commande.
La commande est la partie qui se trouve entre les crochets, c'est à dire :
{/#[ ]*visible_hostname/a\\
visible_hostname $HOSTNAME;}
ETAPE 6:
--------
/#[ ]*visible_hostname/a
se décompose en en deux parties:
/ADRESSE/fonction
#[ ]*visible_hostname
Demande a sed de traiter la chaîne de caractères qui commence par le caractère #, qui contient éventuellement des caractères espaces et qui finie par la chaîne de caractères visible_hostname
/#[ ]*visible_hostname/a
on peut voir l'utilisation de la fonction "a" à la fin.
Cela signifie que tu texte va être ajoute après la ligne qui correspond à l'expression rationnelle suivante:
#[ ]*visible_hostname
ETAPE 7:
--------
visible_hostname $HOSTNAME;
Pour finir, le texte ajouter est le suivant:
visible_hostname $HOSTNAME
$HOSTNAME correspond à la variable d'environnement.
Pour connaitre son contenu il suffit de taper :
echo $HOSTNAME
CONCLUSION:
-----------
Ce script sed initialise la variable squid visible_hostname avec la valeur $HOSTNAME de votre environnement Shell.
voila j'ai bien saisi , merci bien romain merci encore mille fois maintenant je suis :-)
RépondreSupprimerBonjour, j'aurai voulu savoir comment passer un numéro de ligne en paramètre dans sed.
RépondreSupprimerJe m'explique :
J'ai un script qui récupère un numéro de ligne dans une variable $TOTO et je voudrai supprimer cette ligne avec sed mais je n'y arrive pas. Par contre si j'utilise un numéro de ligne directement cela fonctionne.
La ligne qui ne marche pas
sed -i {$TOTO}d test.conf
La ligne qui marche
sed -i 97d test.conf
J'ai fait plusieurs essais avec des \ des quotes mais je n'ai pas trouvé...(ouais sur ce coup là je suis mauvais)
Peux-tu éclairer ma chandelle ?
Bonjour John,
RépondreSupprimerAu lieu de la commande: sed -i {$TOTO}d test.conf
essayes plutot ceci:
sed -i ${TOTO}d test.conf
ou
sed -i "${TOTO}d" test.conf
Tiens moi au courant :)
Bonjour,
RépondreSupprimerJ'ai un souci je voudrai récupérer dans un fichier texte une valeur comme ceci par exemple "12,45" et la transformer en "12.45" en gros "xx,xx" => "xx.xx"
bref j'ai essayé cette ligne de comande
/bin/sed -i -e "\"[1-9]{3},[0-9]{2}\"/\"[1-9]{3}\.[0-9]{2}\"" monfchier
Je me suis rendu compte que la variable de substitution ne peux pas être une expression régulière dans ce que je me demande est ce qu'on sur linux on peut trouvé un equivalent de preg_match() en php pour récupéré la valeur et la modifier.
Merci d'avance.
Débutant sur linux
Mr Anas
Il faut pour cela utiliser les variables :
RépondreSupprimersed -ie "s#\(\"[0-9]*\),\([0-9]*\"\)#\1.\2#g" fichier
il faut mettre une expression entre parentheses comme cela \( EXPRESSION1 \) puis \( EXPRESSION2 \) et recuperer ce que tu as mis entre parentheses grace à \1 puis \2 ....etc
Excellent tutoriel, qui plus est en français, je suis un pro sed maintenant :p merci pour ta contribution.
RépondreSupprimerBonjour à tous, tout d'abord, excellent tuto ! j'ai une petite question : je dispose d'un fichier qui contient le type d'information suivante :
RépondreSupprimerproduit:98:2450
Cout:19421 21959Necessaire pour le produit 99:2538
Je souhaite conserver uniquement les valeurs 98 et 99:2538, qui peuvent etre des valeurs avec plusieurs chiffres.
j'arrive à créer une regex qui correspond à ces valeurs : [0-9]+:[0-9]+$ ; mais je n'arrive pas à garder que ça...
une petite aide?
Bonjour à tous, effectivement ce tutoriel est bien complet, et m'a pas mal déjà aidé; vu qu'il ya des experts, je me permet de poser ma question ici :
RépondreSupprimerje souhaiterai enlever chaque lignes dont le caractère (exemple A) est répété plus de 2 fois dans la totalité de la ligne et non, pas seulement 2 fois à la suite (même si quelque part cela revient au memme ... j'ai d'ailleur cette commande qui le fait : sed '/\([A-Z]\|[A-Z]\1\{2,\}/d' elle supprime uniquement 2 fois le même caractère à la suite compris entre A à Z)
Donc se serait pour ma demande l'exemple suivant :
ABCD => conservé
ABCA => supprimé il ya + de 2 fois le A dans la ligne
AABC => supprimé exemple de ma commande citée ci-dessus (2 fois de suite le A)
BCDAD => supprimé il ya + de 2 fois le D dans la ligne
BCACCC => supprimé il ya plus de 2 fois le C dans la ligne
Voilà, c'est pas simple mais merci d'avance pour une réponse.
Bonjour,
SupprimerÉlimination des lignes contenant au moins 2 fois le même caractère
je propose en test :
echo -e "ABCD\nABCA\nAABC\nBCDAD\nBCACCC\nCHROMO\nSOME\nCQFD" |sed -e "/\([A-Z]\).*\1/d";
cela retourne :
ABCD
SOME
CQFD
En espérant aider quelqu'un.
(par ailleurs, c'est une page très intéressante pour les rappels, merci)
Stéphane
Bonjour,
RépondreSupprimerPour chaque ligne d'un fichierX, je voudrais remplacer toutes les balises qui commencent par par la balise . La problématique est que la ligne peut comporter plusieurs caractères < et >
Pour exemmple, remplacer :
Par :
Merci d'avance pour votre aide
Bonjour,
RépondreSupprimerPour chaque ligne d'un fichierX, je voudrais remplacer toutes les balises qui commencent par "" par ". La problématique est que la ligne peut comporter plusieurs caractères < et >
Merci
Bonjour,
RépondreSupprimerPour chaque ligne d'un fichierX, je voudrais remplacer toutes les balises qui commencent par "GETAUX.." par "GETAUX". La problématique est que la ligne peut comporter plusieurs caractères " et "
En clair, susbstituer toutes les lignes qui commenecent par "GETAUX jusqu'au 1er " rencontré par "GETAUX"
Merci
Merci
Salut ! Tout le monde, j'ai trouvé intéressante le tutoriel et les commentaires.
RépondreSupprimerJ'aimerai pouvoir remplacer dans un fichier entre deux balises une valeur indiquée.
Bonjour,
SupprimerRemplacement d'une valeur entre 2 balises (exemple sous linux)
echo "debut3.14fin" |sed -e 's:\(\).*\(<\/TAG>\):\1PI\2:';
donne:
debutPIfin
En espérant aider quelqu'un.
Stéphane
Correction:
Supprimerecho 'debut BALISE 3.14 /BALISE fin' |sed -e 's:\(BALISE\).*\(\/BALISE\):\1 pi \2:';
debut BALISE pi /BALISE fin
Remplacer BALISE par ce qui vous intéresse.
(petit problème d'affichage de la réponse
avec (caractère INF)BALISE(caractère SUP)
Désolé
Stéphane
Bonjour,
RépondreSupprimerRéponse pour "GETAUX... en début de ligne
echo -e "\"GETAUX1 un peu\" tagada \"suite\" \"GETAUX 2\" \"UN\"\n\"GETAUX 3 beaucoup \" tsoin-tsoin \"DEUX\"\nTROIS\"GETAUX4 pas du tout\" fin"
donne:
"GETAUX1 un peu" tagada "suite" "GETAUX 2" "UN"
"GETAUX 3 beaucoup " tsoin-tsoin "DEUX"
TROIS"GETAUX4 pas du tout" fin
mais avec |sed -e 's:^"GETAUX\([^"]*\)":"GETAUX":g'
on a:
"GETAUX" tagada "suite" "GETAUX 2" "UN"
"GETAUX" tsoin-tsoin "DEUX"
TROIS"GETAUX4 pas du tout" fin
Est-ce que cela répond bien à la question ?