Utilisation de sed en ligne de commande
Exemples avec le fichier depts2012.txt (téléchargeable sur le site de l'INSEE à cette adresse : http://isbeta.fr/f8c21)
$ cat depts2012.txt
REGION DEP CHEFLIEU TNCC NCC NCCENR
82 01 01053 5 AIN Ain
22 02 02408 5 AISNE Aisne
83 03 03190 5 ALLIER Allier
93 04 04070 4 ALPES-DE-HAUTE-PROVENCE Alpes-de-Haute-Provence
93 05 05061 4 HAUTES-ALPES Hautes-Alpes
93 06 06088 4 ALPES-MARITIMES Alpes-Maritimes
82 07 07186 5 ARDECHE Ardèche
...
11 94 94028 2 VAL-DE-MARNE Val-de-Marne
11 95 95500 2 VAL-D'OISE Val-d'Oise
01 971 97105 3 GUADELOUPE Guadeloupe
02 972 97209 3 MARTINIQUE Martinique
03 973 97302 3 GUYANE Guyane
04 974 97411 0 LA REUNION La Réunion
06 976 97608 0 MAYOTTE Mayotte
$
La commande d (delete)
La commande d permet de ne pas afficher à l'écran les lignes sélectionnées par la partie adresse.
Exemple :
Ne pas afficher les lignes contenant les caractères de a à h (en minuscule)
$ sed '/[a-h]/d' depts2012.txt
REGION DEP CHEFLIEU TNCC NCC NCCENR
82 01 01053 5 AIN Ain
73 46 46042 2 LOT Lot
$
La commande p (print)
La commande p permet d'afficher à l'écran les lignes sélectionnées par la partie adresse. Par défauf, sed affiche également tout le contenu du fichier. Pour modifier ce comportement, il faut utiliser l'option -n.
Exemple :
Afficher les lignes 1 à 4. Par défaut, sed affiche en plus tout le contenu du fichier. Les lignes demandées apparaissent donc en double.
$ sed '1,4p' depts2012.txt
REGION DEP CHEFLIEU TNCC NCC NCCENR
REGION DEP CHEFLIEU TNCC NCC NCCENR
82 01 01053 5 AIN Ain
82 01 01053 5 AIN Ain
22 02 02408 5 AISNE Aisne
22 02 02408 5 AISNE Aisne
83 03 03190 5 ALLIER Allier
83 03 03190 5 ALLIER Allier
93 04 04070 4 ALPES-DE-HAUTE-PROVENCE Alpes-de-Haute-Provence
93 05 05061 4 HAUTES-ALPES Hautes-Alpes
93 06 06088 4 ALPES-MARITIMES Alpes-Maritimes
....
$
L'option -n permet de ne pas afficher le reste du fichier.
$ sed -n '1,4p' depts2012.txt
REGION DEP CHEFLIEU TNCC NCC NCCENR
82 01 01053 5 AIN Ain
22 02 02408 5 AISNE Aisne
83 03 03190 5 ALLIER Allier
$
Il est également possible d'afficher 1 ligne toutes les n lignes
$ sed -n '1~4p' depts2012.txt
Cette commande permet d'afficher à partir de la ligne 1 du fichier puis toutes les 4 lignes, c'est à dire les lignes 1, 5, 9, 13 etc etc
$ sed -n '0~4p' depts2012.txt
Cette commande permet d'afficher à partir de la ligne 4 du fichier puis toutes les 4 lignes, c'est à dire les lignes 4, 8, 12, 16 etc etc
Pour info, ce type d'adressage est valable pour les commandes delete, print, write
La commande suivante permet de rechercher un motif précis et d'afficher uniquement la ligne suivante.
$ sed -n '/ANSWER SECTION/{n;p}' <(dig a quennec.fr)
quennec.fr. 906 IN A 51.159.70.99
La première partie '/ANSWER SECTION/' correspond au motif recherché.
Ensuite, '{n;p}', un bloc d'instruction qui est exécuté si le motif recherché est trouvé.
La command 'n' permet de sauter à la ligne suivante.
La commande 'p' permet d'afficher la ligne courante.
et si l'on souhaite afficher plusieurs lignes après le motif recherché
$ dig any quennec.fr | sed -n '/ANSWER SECTION/{:a ; n ; /^$/q ; p ; ba}'
quennec.fr. 3183 IN A 51.159.70.99
quennec.fr. 21400 IN NS ns42.infomaniak.com.
quennec.fr. 21400 IN NS ns41.infomaniak.com.
quennec.fr. 21400 IN SOA ns41.infomaniak.com. hostmaster.infomaniak.ch. 2024091604 10800 3600 605800 86400
quennec.fr. 3400 IN MX 5 mta-gw.infomaniak.ch.
quennec.fr. 3368 IN TXT "v=spf1 a mx ip4:99.162.140.135ip4:51.159.70.99 include:spf.infomaniak.ch -all"
Ce qui change vis à vis de la commande précédente:
Dans le bloc d'instruction '{:a ; n ; /^$/q ; p ; ba}', la première commande ':a' permet d'initialiser un label, la commande 'n' permet de passer à la ligne suivante (pas de changement), la commande '/^$/q' permet de mettre fin au traitement dès qu'une ligne vide est rencontrée, la commande 'p' permet d'afficher la ligne en cours de traitement (pas de changement), et enfin, la commande 'ba' permet de revenir au label 'a' précédement initialisé et de continuer le traitement sur la ligne suivante (à voir comme une boucle) etc etc ...
La commande w (write)
La commande w permet d'écrire dans un fichier les lignes sélectionnées par la partie adresse. Comme pour la commande p, sed affiche également tout le contenu du fichier à l'écran. Pour modifier ce comportement, il faut utiliser l'option -n.
Exemple :
Stocker dans un fichier "depts3x" toutes les villes dont le code postal commence par 3 et dans le fichier "depts6x" toutes les villes dont le code postal commence par 6.
$ sed -n -e '/3[0-9]\{4\}/w depts3x' -e '/6[0-9]\{4\}/w depts6x' depts2012.txt
$ cat depts3x
91 30 30189 2 GARD Gard
73 31 31555 3 HAUTE-GARONNE Haute-Garonne
73 32 32013 2 GERS Gers
72 33 33063 3 GIRONDE Gironde
91 34 34172 5 HERAULT Hérault
53 35 35238 1 ILLE-ET-VILAINE Ille-et-Vilaine
24 36 36044 5 INDRE Indre
24 37 37261 1 INDRE-ET-LOIRE Indre-et-Loire
82 38 38185 5 ISERE Isère
43 39 39300 2 JURA Jura
$ cat depts6x
22 60 60057 5 OISE Oise
25 61 61001 5 ORNE Orne
31 62 62041 2 PAS-DE-CALAIS Pas-de-Calais
83 63 63113 2 PUY-DE-DOME Puy-de-Dôme
72 64 64445 4 PYRENEES-ATLANTIQUES Pyrénées-Atlantiques
73 65 65440 4 HAUTES-PYRENEES Hautes-Pyrénées
91 66 66136 4 PYRENEES-ORIENTALES Pyrénées-Orientales
42 67 67482 2 BAS-RHIN Bas-Rhin
42 68 68066 2 HAUT-RHIN Haut-Rhin
82 69 69123 2 RHONE Rhône
$
Négation d'une commande (!)
Le caractère ! placé devant une commande permet d'exécuter cette dernière sur toutes les lignes sauf sur celles correspondant à la partie adresse.
Exemple :
Ne pas afficher les lignes contenant les caractères de a à h (en minuscule)
$ sed -n '/[a-h]/!p' depts2012.txt
REGION DEP CHEFLIEU TNCC NCC NCCENR
82 01 01053 5 AIN Ain
73 46 46042 2 LOT Lot
$
La commande s (substitution)
La commande s permet de substituer une chaine de caractères par une autre sur les lignes sélectionnées par la partie adresse.
Pour substituer des noms de fichiers avec la commande sed, utiliser le pipe '|' comme séparateur à cause du slash '/' dans les noms de fichiers.
$ sed -i "s|/fichier1|/fichier2|g" maListeDeFichiers
Premier exemple :
Remplacer toutes les chaines contenant '-et-' ou '-ET-' par ' & '
$ sed -n '/-et-/p' depts2012.txt
24 28 28085 1 EURE-ET-LOIR Eure-et-Loir
53 35 35238 1 ILLE-ET-VILAINE Ille-et-Vilaine
24 37 37261 1 INDRE-ET-LOIRE Indre-et-Loire
24 41 41018 0 LOIR-ET-CHER Loir-et-Cher
72 47 47001 0 LOT-ET-GARONNE Lot-et-Garonne
52 49 49007 0 MAINE-ET-LOIRE Maine-et-Loire
41 54 54395 0 MEURTHE-ET-MOSELLE Meurthe-et-Moselle
26 71 71270 0 SAONE-ET-LOIRE Saône-et-Loire
11 77 77288 0 SEINE-ET-MARNE Seine-et-Marne
73 82 82121 0 TARN-ET-GARONNE Tarn-et-Garonne
$
$ sed -e 's/-et-/ \& /g' -e 's/-ET-/ \& /g' depts2012.txt | sed -n '/ \& /p'
24 28 28085 1 EURE & LOIR Eure & Loir
53 35 35238 1 ILLE & VILAINE Ille & Vilaine
24 37 37261 1 INDRE & LOIRE Indre & Loire
24 41 41018 0 LOIR & CHER Loir & Cher
72 47 47001 0 LOT & GARONNE Lot & Garonne
52 49 49007 0 MAINE & LOIRE Maine & Loire
41 54 54395 0 MEURTHE & MOSELLE Meurthe & Moselle
26 71 71270 0 SAONE & LOIRE Saône & Loire
11 77 77288 0 SEINE & MARNE Seine & Marne
73 82 82121 0 TARN & GARONNE Tarn & Garonne
$
Second exemple :
Travailler sur le contenu d'une variable.
$ arg=fic1,fic2,fic3
$ echo $arg
fic1,fic2,fic3
$ echo $arg | sed 's/,/ /g' # On remplace les virgules par des espaces
fic1 fic2 fic3
$ liste_arg=$(echo $arg | sed 's/,/ /g')
$ echo $liste_arg
fic1 fic2 fic3
$ for argt in $liste_arg
> do
> echo $argt
> done
fic1
fic2
fic3
$
Troisième exemple :
Le caractère "&" utilisée dans la partie remplacement représente la chaine correspondant à l'expression régulière.
$ tail depts2012.txt
11 91 91228 5 ESSONNE Essonne
11 92 92050 4 HAUTS-DE-SEINE Hauts-de-Seine
11 93 93008 3 SEINE-SAINT-DENIS Seine-Saint-Denis
11 94 94028 2 VAL-DE-MARNE Val-de-Marne
11 95 95500 2 VAL-D'OISE Val-d'Oise
01 971 97105 3 GUADELOUPE Guadeloupe
02 972 97209 3 MARTINIQUE Martinique
03 973 97302 3 GUYANE Guyane
04 974 97411 0 LA REUNION La Réunion
06 976 97608 0 MAYOTTE Mayotte
$ tail depts2012.txt | sed 's/.*/|&|/'
|11 91 91228 5 ESSONNE Essonne|
|11 92 92050 4 HAUTS-DE-SEINE Hauts-de-Seine|
|11 93 93008 3 SEINE-SAINT-DENIS Seine-Saint-Denis|
|11 94 94028 2 VAL-DE-MARNE Val-de-Marne|
|11 95 95500 2 VAL-D'OISE Val-d'Oise|
|01 971 97105 3 GUADELOUPE Guadeloupe|
|02 972 97209 3 MARTINIQUE Martinique|
|03 973 97302 3 GUYANE Guyane|
|04 974 97411 0 LA REUNION La Réunion|
|06 976 97608 0 MAYOTTE Mayotte|
$
Toutes les chaines ont été encadrées par des pipes "|"
Quatrième exemple :
Récupérer les codes postaux et les noms des départements (en majuscule) afin d'effectuer une mise en forme particulière.
Utilisation de la mémorisation grâce aux caractères \( \) afin de les réafficher avec \1 et \2.
$ tail depts2012.txt
11 91 91228 5 ESSONNE Essonne
11 92 92050 4 HAUTS-DE-SEINE Hauts-de-Seine
11 93 93008 3 SEINE-SAINT-DENIS Seine-Saint-Denis
11 94 94028 2 VAL-DE-MARNE Val-de-Marne
11 95 95500 2 VAL-D'OISE Val-d'Oise
01 971 97105 3 GUADELOUPE Guadeloupe
02 972 97209 3 MARTINIQUE Martinique
03 973 97302 3 GUYANE Guyane
04 974 97411 0 LA REUNION La Réunion
06 976 97608 0 MAYOTTE Mayotte
$ tail depts2012.txt | sed "s/^[0-9]\{2\}[ \t]*[0-9]\{2,3\}[ \t]*\([0-9]\{5\}\)[ \t]*[0-9][ \t]*\([-A-Z_\. ']\{1,\}\)[ \t]*.\{1,\}$/Code postal : \1\tDepartement : \2/"
Code postal : 91228 Departement : ESSONNE
Code postal : 92050 Departement : HAUTS-DE-SEINE
Code postal : 93008 Departement : SEINE-SAINT-DENIS
Code postal : 94028 Departement : VAL-DE-MARNE
Code postal : 95500 Departement : VAL-D'OISE
Code postal : 97105 Departement : GUADELOUPE
Code postal : 97209 Departement : MARTINIQUE
Code postal : 97302 Departement : GUYANE
Code postal : 97411 Departement : LA REUNION
Code postal : 97608 Departement : MAYOTTE
$
Cinquième exemple :
Exemples détaillés de l'option g dans la commande de substitution s.
$ arg=val1,val2,val3,val4
$ echo $arg
val1,val2,val3,val4
Remplacement de la globalité des virgules par des espaces grâce à l'option g.
$ echo $arg | sed 's/,/ /g'
val1 val2 val3 val4
Sans l'option g, seule la première virgule rencontrée est remplacée par un espace.
$ echo $arg | sed 's/,/ /'
val1 val2,val3,val4
Le chiffre 1 permet le remplacement de la première virgule rencontrée. Identique à la commande précédente.
$ echo $arg | sed 's/,/ /1'
val1 val2,val3,val4
Le chiffre 3 permet le remplacement de la troisième virgule rencontrée.
$ echo $arg | sed 's/,/ /3'
val1,val2,val3 val4
Commentaires
Erwan (non vérifié)
mar, 21/11/2017 - 12:21
Permalien
Merci !
Bien présenté, bien expliqué, exemples variés.
Très bon travail !
ronan
mar, 21/11/2017 - 14:16
Permalien
C'est gentil ...
... merci pour vos compliments.
Ajouter un commentaire