Articles

Apprendre les commandes Linux : sed

Posted on

Bienvenue dans la deuxième partie de notre série, une partie qui se concentrera sur sed, la version GNU. Comme vous le verrez, il existe plusieurs variantes de sed, qui est disponible pour pas mal de plateformes, mais nous allons nous concentrer sur les versions 4.x de GNU sed. Beaucoup d’entre vous ont déjà entendu parler de sed et l’ont déjà utilisé, principalement comme outil de substitution. Mais ce n’est qu’une partie de ce que sed peut faire, et nous ferons de notre mieux pour vous montrer autant que possible ce que vous pouvez faire avec lui. Le nom signifie Stream EDitor, et ici « stream » peut être un fichier, un pipe ou simplement stdin. Nous nous attendons à ce que vous ayez des connaissances de base de Linux et si vous avez déjà travaillé avec des expressions régulières ou si vous savez au moins ce qu’est une regexp, c’est encore mieux. Nous n’avons pas la place pour un tutoriel complet sur les expressions régulières, donc à la place nous vous donnerons seulement une idée de base et beaucoup d’exemples sed. Il y a beaucoup de documents qui traitent du sujet, et nous aurons même quelques recommandations, comme vous le verrez dans une minute.

Installation

Il n’y a pas grand-chose à dire ici, car il y a de fortes chances que vous ayez déjà installé sed, car il est utilisé dans divers scripts système et un outil précieux dans la vie d’un utilisateur Linux qui veut être efficace. Vous pouvez tester quelle version vous avez en tapant

 $ sed --version

Sur mon système, cette commande m’indique que j’ai installé GNU sed 4.2.1, plus des liens vers la page d’accueil et d’autres trucs utiles. Le paquet est nommé simplement ‘sed’ quelle que soit la distribution, mais si Gentoo offre sed implicitement, je crois que cela signifie que vous pouvez être rassuré.

Concepts

Avant d’aller plus loin, nous pensons qu’il est important de souligner ce que fait exactement sed, car « éditeur de flux » peut ne pas sonner trop de cloches. sed prend le texte d’entrée, effectue les opérations spécifiées sur chaque ligne (sauf indication contraire) et imprime le texte modifié. Les opérations spécifiées peuvent être append, insert, delete ou substitute. Ce n’est pas aussi simple qu’il n’y paraît : soyez prévenu qu’il existe un grand nombre d’options et de combinaisons qui peuvent rendre une commande sed plutôt difficile à digérer. Donc si vous voulez utiliser sed, nous vous recommandons d’apprendre les bases des regexps, et vous pourrez attraper le reste au fur et à mesure. Avant de commencer le tutoriel, nous voulons remercier Eric Pement et d’autres pour l’inspiration et pour ce qu’il a fait pour tous ceux qui veulent apprendre et utiliser sed.

Looking for Linux Systems Analyst !
L’Institut Géophysique de l’UAF, est à la recherche d’un analyste de systèmes Linux expérimenté pour rejoindre son équipe d’analystes et d’ingénieurs en cyber infrastructure de recherche. LIEU : Fairbanks, Alaska, USA
APPLIEZ MAINTENANT

Expressions régulières

Comme les commandes/scripts sed ont tendance à devenir cryptiques, nous pensons que nos lecteurs doivent comprendre les concepts de base au lieu de copier et coller aveuglément des commandes dont ils ne connaissent pas la signification. Lorsque l’on veut comprendre ce qu’est une regexp, le mot clé est « matching ». Ou encore mieux, « correspondance de motifs ». Par exemple, dans un rapport destiné à votre département des ressources humaines, vous avez écrit le nom de Nick en référence à l’architecte réseau. Mais Nick est parti et John est venu prendre sa place. Vous devez donc remplacer le mot Nick par John. Si le fichier s’appelle report.txt, vous pourriez faire

 $ cat report.txt | sed 's/Nick/John/g' > report_new.txt

Par défaut, sed utilise stdout, vous pouvez donc utiliser l’opérateur de redirection de votre shell, comme dans notre exemple ci-dessous. Il s’agit d’un exemple des plus simples, mais nous avons illustré quelques points : nous faisons correspondre le motif  » Nick  » et nous remplaçons toutes les instances par  » John « . Notez que sed est sensible à la casse, donc soyez prudent et vérifiez votre fichier de sortie pour voir si toutes les substitutions ont été faites. Ce qui précède aurait également pu être écrit comme ceci :

 $ sed 's/Nick/John/g' report.txt > report_new.txt

OK, mais où sont les expressions régulières, demandez-vous ? Eh bien, nous voulions d’abord vous mettre le pied à l’étrier avec le concept de correspondance et voici la partie intéressante.

Si vous n’êtes pas sûr d’avoir écrit  » nick  » par erreur au lieu de  » Nick  » et que vous voulez également faire correspondre cela, vous pouvez utiliser sed ‘s/Nick|nick/John/g’. La barre verticale a la même signification que celle que vous connaissez si vous avez utilisé C, c’est-à-dire que votre expression correspondra à Nick ou nick. Comme vous le verrez, la barre verticale peut également être utilisée d’autres manières, mais sa signification reste la même. D’autres opérateurs largement utilisés dans les expressions rationnelles sont ‘?’, qui correspondent à zéro ou une instance de l’élément précédent (flavou?r correspondra à flavor et flavour), ‘*’ signifie zéro ou plus et ‘+’ correspond à un ou plusieurs éléments. ^  » correspond au début de la chaîne, tandis que  » $  » fait l’inverse. Si vous êtes un utilisateur de vi(m), certains de ces éléments peuvent vous sembler familiers. Après tout, ces utilitaires, ainsi que awk ou C ont leurs racines dans les premiers jours d’Unix. Nous n’insisterons pas plus sur le sujet, car les choses deviendront plus simples en lisant des exemples, mais ce que vous devez savoir, c’est qu’il existe différentes implémentations des regexps : POSIX, POSIX Extended, Perl ou diverses implémentations d’expressions régulières floues, garanties pour vous donner mal à la tête.

exemples sed

.

Division

Division

Apprentissage de la commande sed de Linux. avec des exemples
Syntaxe des commandes Linux Description des commandes Linux
sed 's/Nick/John/g' report.txt
Remplacer chaque occurrence de Nick par John dans le rapport.txt
sed 's/Nick|nick/John/g' report.txt
Remplacer chaque occurrence de Nick ou nick par John.
sed 's/^/ /' file.txt >file_new.txt
Ajouter 8 espaces à gauche d’un texte pour une jolie impression.
sed -n '/Of course/,/attention you \
pay/p' myfile

Afficher un seul paragraphe, commençant par « Bien sûr »

et se terminant par « attention vous payez »

sed -n 12,18p file.txt
Affichez uniquement les lignes 12 à 18 du fichier.txt
sed 12,18d file.txt
Show all of file.txt sauf les lignes de 12 à 18
sed G file.txt 
Double espacement du fichier.txt
sed -f script.sed file.txt
Écrire toutes les commandes dans le script.sed et les exécuter
sed '5!s/ham/cheese/' file.txt
Remplacer le jambon par le fromage dans le fichier.txt sauf à la 5ème ligne
sed '$d' file.txt
Supprimer la dernière ligne
sed '/\{3\}/p' file.txt
Imprimer uniquement les lignes comportant trois chiffres consécutifs
sed '/boom/!s/aaa/bb/' file.txt

.

Unless boom is found replace aaa with bb
sed '17,/disk/d' file.txt
Delete toutes les lignes de la ligne 17 à ‘disk’
echo ONE TWO | sed "s/one/unos/I"

Remplace un avec unos de manière insensible à la casse.insensible à la casse,

ainsi il imprimera « unos TWO »

sed 'G;G' file.txt
Tripler-espace un fichier
sed 's/.$//' file.txt
Un moyen de remplacer dos2unix 🙂
sed 's/^*//' file.txt
Supprimer tous les espaces devant chaque ligne du fichier.txt
sed 's/*$//' file.txt
Supprimer tous les espaces à la fin de chaque ligne du fichier.txt
sed 's/^*//;s/*$//' file.txt

Supprimer tous les espaces devant et à la fin de chaque ligne

du fichier.txt

sed 's/foo/bar/' file.txt
Remplacer foo par bar uniquement pour la première instance dans une ligne.
sed 's/foo/bar/4' file.txt
Remplacer foo par bar uniquement pour la 4e instance d’une ligne.
sed 's/foo/bar/g' file.txt 
Remplacer foo par bar pour toutes les instances d’une ligne.
sed '/baz/s/foo/bar/g' file.txt
Uniquement si la ligne contient baz, remplacer foo par bar
sed '/./,/^$/!d' file.txt
Supprimer toutes les lignes vierges consécutives lignes vides consécutives, sauf pour EOF
sed '/^$/N;/\n$/D' file.txt

Supprime toutes les lignes vides consécutives, mais autorise

seulement la ligne blanche supérieure

sed '/./,$!d' file.txt

.

Supprimer toutes les lignes vides de tête
sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba' \
file.txt
Suppression de toutes les lignes vides de fin de ligne
sed -e :a -e '/\$/N; s/\\n//; ta' \
file.txt

Si un fichier se termine par une barre oblique inverse, le joindre avec le suivant (utile

pour les scripts shell)

sed '/regex/,+5/expr/'
Match regex plus les 5 lignes suivantes
sed '1~3d' file.txt
Supprimer une ligne sur trois, en commençant par la première
sed -n '2~5p' file.txt
Imprimer toutes les 5 lignes en commençant par la la deuxième
sed 's/ick/John/g' report.txt

Une autre façon d’écrire un exemple ci-dessus.

Vous pouvez deviner laquelle ?

sed -n '/RE/{p;q;}' file.txt

Imprimer seulement la première correspondance de

RE (expression régulière)

.

sed '0,/RE/{//d;}' file.txt
Supprimer uniquement la première correspondance
sed '0,/RE/s//to_that/' file.txt
Changer uniquement la première correspondance
sed 's/^*,/9999,/' file.csv
Changer le le premier champ à 9999 dans un fichier CSV
s/^ *\(.*\) *$/||/;
s/" *, */"|/g;
: loop
s/| *\(*\) *, */||/g;
s/| *, */||/g;
t loop
s/ *|/|/g;
s/| */|/g;
s/^|\(.*\)|$//;

sed script pour convertir un fichier CSV en bar-séparées

(ne fonctionne que sur certains types de CSV,

avec des « s » intégrés et des virgules)

sed ':a;s/\(^\|\)\(\+\)\
(\{3\}\)/,/g;ta' file.txt
Changer les chiffres du fichier.txt de la forme 1234.56 à 1.234.56
sed -r "s/\<(reg|exp)+/\U&/g"
Convertir n’importe quel mot commençant par reg ou exp en majuscule
sed '1,20 s/Johnson/White/g' file.txt

Faire le remplacement de Johnson par les Blancs uniquement sur

les lignes entre 1 et 20

sed '1,20 !s/Johnson/White/g' file.txt
Ce qui précède inversé (correspond à toutes les lignes sauf les lignes 1-.20)
sed '/from/,/until/ { s/\<red\>/magenta/g; \
s/\<blue\>/cyan/g; }' file.txt
Remplacer seulement entre « de » et « jusqu’à »
sed '/ENDNOTES:/,$ { s/Schaff/Herzog/g; \
s/Kraft/Ebbing/g; }' file.txt
Remplacer uniquement du mot « ENDNOTES : » jusqu’à EOF
sed '/./{H;$!d;};x;/regex/!d' file.txt
Imprimer les paragraphes uniquement s’ils contiennent… regex
 sed -e '/./{H;$!d;}' -e 'x;/RE1/!d;\
/RE2/!d;/RE3/!d' file.txt

Imprimer les paragraphes uniquement s’ils contiennent RE1,

RE2 et RE3

 sed ':a; /\$/N; s/\\n//; ta' file.txt

Joindre deux lignes dont la première se termine par une barre oblique inversée

 sed 's/14"/fourteen inches/g' file.txt

C’est ainsi que vous pouvez pouvez utiliser les guillemets doubles

 sed 's/\/some\/UNIX\/path/\/a\/new\
/path/g' file.txt

Travailler avec les chemins d’accès Unix paths

 sed 's///g' file.txt

Supprimer tous les caractères de a à g du fichier.txt

sed 's/\(.*\)foo/bar/' file.txt
Remplacer uniquement la dernière correspondance de foo avec bar
sed '1!G;h;$!d' 

.

Un remplacement tactique
sed '/\n/!G;s/\(.\)\(.*\n\)/&\
/;//D;s/.//'
A rev replacement
sed 10q file.txt
Un remplacement de la tête
sed -e :a -e '$q;N;11,$D;ba' \
file.txt
Un remplacement de queue
sed '$!N; /^\(.*\)\n$/!P; D' \
file.txt
Un remplacement uniq
sed '$!N; s/^\(.*\)\n$//;\
t; D' file.txt
L’opposé (ou uniq -d équivalent)
sed '$!N;$!D' file.txt
Equivalent à queue -n 2
sed -n '$p' file.txt
… tail -n 1 (ou tail -1)
sed '/regexp/!d' file.txt
équivalentgrep
sed -n '/regexp/{g;1!p;};h' file.txt

Imprimer la ligne précédant celle qui correspond au regexp, mais

pas celle qui contient le regexp

sed -n '/regexp/{n;p;}' file.txt
Imprimer la ligne après celle qui correspond au regexp, mais

pas celle contenant le regexp

sed '/pattern/d' file.txt
Supprimer les lignes correspondant au motif
sed '/./!d' file.txt
Supprimer toutes les lignes vides d’un un fichier
sed '/^$/N;/\n$/N;//D' file.txt
.

Supprimez toutes les lignes vides consécutives

à l’exception des deux premières

sed -n '/^$/{p;h;};/./{x;/./p;}'\
file.txt
Supprimez la dernière ligne de chaque paragraphe
sed 's/.\x08//g' file
Suppression des nroff overstrikes
sed '/^$/q'
Get mail header
sed '1,/^$/d'

.

Get mail body
sed '/^Subject: */!d; s///;q'
Get mail subject
.

sed 's/^/> /'

Citer le message du courrier en insérant un

« >  » devant chaque ligne

sed 's/^> //'
Le contraire (message de courrier non cité)
sed -e :a -e 's/<*>//g;/</N;//ba'
Supprimez les balises HTML
sed '/./{H;d;};x;s/\n/={NL}=/g'\
file.txt | sort \
| sed '1s/={NL}=//;s/={NL}=/\n/g'
Trier les paragraphes du fichier .txt par ordre alphabétique
sed 's@/usr/bin@&/local@g' path.txt
Remplacer /usr/bin par /usr/bin/local dans le chemin.txt
sed 's@^.*$@<<<&>>>@g' path.txt
essayer et voir 🙂
sed 's/\(\/*\).*//g' path.txt

Provided path.txt contient $PATH, ceci va

échoquer uniquement le premier chemin sur chaque ligne

sed 's/\(*\).*//' /etc/passwd

remplacement de l’awk -. affiche uniquement les utilisateurs

du fichier passwd

echo "Welcome To The Geek Stuff" | sed \
's/\(\b\)/\(\)/g'
(W)elcome (T)o (T)he (G)eek (S)tuff
Self-explicative
sed -e '/^$/,/^END/s/hills/\
mountains/g' file.txt

Échanger ‘collines’ contre ‘montagnes’, mais uniquement sur des blocs

de texte commençant

par une ligne blanche, et se terminant par une ligne commençant

par les trois caractères ‘END’, inclus

sed -e '/^#/d' /etc/services | more
Visualiser le fichier des services sans les lignes commentées lignes
sed '$s@\(*\):\(*\):\(*\
\)@::@g' path.txt
Inverser l’ordre des éléments dans la dernière ligne de path.txt
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}'\
-e h file.txt

Imprimer 1 ligne de contexte avant et après la ligne correspondante,

avec un numéro de ligne où la correspondance se produit

sed '/regex/{x ;p;x;}' fichier.txt
Insérer une nouvelle ligne au-dessus de chaque ligne correspondant au regex
sed '/AAA/!d; /BBB/!d; /CCC/!d' file.txt
Correspondre AAA, BBB et CCC dans cet ordre
sed '/AAA.*BBB.*CCC/!d' file.txt
Rattacher AAA, BBB et CCC dans cet ordre
sed -n '/^.\{65\}/p' file.txt
Imprimer les lignes de 65 caractères ou plus
sed -n '/^.\{65\}/!p' file.txt
Imprimer les lignes de 65 charactères ou moins
sed '/regex/G' file.txt
Insérer une ligne vierge sous chaque ligne
sed '/regex/{x;p;x;G;}' file.txt
Insérer une ligne blanche au-dessus et en dessous
sed = file.txt | sed 'N;s/\n/\t/'
Nombre de lignes dans le fichier.txt
sed -e :a -e 's/^.\{1,78\}$/\
&/;ta' fichier.txt
Alignement du texte à droite
sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e \
's/\( *\)//' fichier.txt
Alignement du texte au centre

Conclusion

Ce n’est qu’une partie de ce que l’on peut raconter sur sed, mais cette série est conçue comme un guide pratique, nous espérons donc qu’elle vous aidera à découvrir la puissance des outils Unix et à devenir plus efficace dans votre travail.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *