Dans un article précédent, j'ai expliqué comment manipuler du texte avec grep
. Maintenant, portez votre attention sur le sed
(Stream Editor), qui est le mieux adapté pour être utilisé dans les pipelines (données provenant d'un canal). Le sed
L'utilitaire peut être utilisé pour imprimer le contenu d'un fichier, substituer une ligne (ou plusieurs lignes), puis enregistrer le fichier. Contrairement à grep
, sed
peut substituer une ligne ou plusieurs lignes dans un fichier et effectuer un sur place mise à jour de ce fichier.
Le sed
le plus simple invocation lors de la substitution de foo
pour bar
est :
$ sed 's/foo/bar/' inputfile
Exemple :Supprimer des commentaires
Tandis que grep
peut formater la sortie à l'écran, il est incapable de modifier un fichier en place. Pour ce faire, vous aurez besoin d'un éditeur de fichiers comme ed
. Depuis ed
ne fait pas partie de cet article, utilisez sed
pour obtenir la même chose que vous avez fait avec grep
dans le premier exemple de l'article précédent. Cette fois, modifiez le /etc/fstab
fichier sur place en passant le -i
indicateur à sed
. Sans le -i
flag , vous ne verriez que ce qui aurait été modifié.
Nous vous encourageons à toujours exécuter sed
sans le -i
flag, juste pour s'assurer que le résultat qu'il produit est attendu. Le sed
l'utilitaire propose également le -i.bak
drapeau, qui crée un fichier de sauvegarde avant de le modifier.
Le dernier grep
commande pour cet exemple était :
$ grep -v '^#' /etc/fstab > ~/fstab_without_comment
Avec sed
, vous avez :
# sed -i '/^#/d' /etc/fstab
/dev/mapper/VGCRYPTO-ROOT / ext4 defaults,x-systemd.device-timeout=0 1 1
UUID=e9de0f73-ddddd-4d45-a9ba-1ffffa /boot ext4 defaults 1 2
LABEL=SSD_SWAP swap swap defaults 0 0
Exemple :Imprimer uniquement /etc/passwd
utilisateurs
Dans le grep
Par exemple, vous n'avez imprimé que les noms d'utilisateur de /etc/passwd
fichier avec ce qui suit :
$ grep -Eo '^[a-zA-Z_-]+' /etc/passwd
Vous pouvez faire la même chose en utilisant sed
comme suit :
$ sed 's/^\([a-zA-Z_-]\+\).*/\1/' /etc/passwd
Dans l'exemple ci-dessus, vous regroupez une correspondance entre parenthèses ()
, puis imprimez le groupe correspondant avec \1
(back-reference), qui dicte le premier groupe. Pour un deuxième groupe, vous utiliseriez \2
, et ainsi de suite.
Exemple : Remplacer tous foo
avec bar
Dans sed
, vous pouvez rechercher un modèle, puis remplacer uniquement l'occurrence correspondant au modèle. Pour remplacer toutes les occurrences dans le fichier inputfile1
de foo
à bar
globalement, exécutez :
$ sed -i '/foo/bar/g' inputfile1
Exemple :remplacer une seule instance
Prenez le fichier inputfile2
, dont le contenu est le suivant :
hello world
second line should be replaced
this line should be replaced later
Dites que vous voulez remplacer should
avec will
, mais uniquement pour la deuxième ligne. Cette commande se décompose comme suit :
$ sed '/second/s/should/will/' inputfile2
| | | |
| | | with this pattern
| | this pattern
| substitute
Search for the pattern "second"
Cette sortie est envoyée à la sortie standard plutôt que de remplacer le contenu du fichier. Le résultat ressemble à ceci :
$ sed '/second/s/should/will/' inputfile2
hello world
second line will be replaced
this line should be replaced later
Le sed
La commande est sensible à la casse. Les éléments suivants ne fonctionneront pas si vous essayez de remplacer World
avec there
:
$ echo "Hello World" | sed 's/world/there/'
Hello World
GNU sed
introduit un nouveau drapeau, /I
, qui ignore la casse et va effectuez le remplacement avec la même commande :
$ echo "Hello World" | sed 's/world/there/I'
Hello there
Exemple :Imprimer une série de lignes et quitter
Avec sed
, vous pouvez également imprimer des lignes et quitter une fois vos critères remplis. Les commandes suivantes imprimeront trois lignes et quitteront. Cette commande :
$ sed -n '1,3p' /etc/passwd
est équivalent à :
$ sed '3q' /etc/passwd
Ce qui suit serait faux :
$ sed '1,3q' /etc/passwd # Wrong. You cannot quit three times
Exemple :Commentez les lignes non commentées
Les expressions régulières peuvent également être utilisées avec sed
, comme démontré précédemment. Par exemple, vous avez le petit script suivant :
$ cat test_script
#/usr/bin/env bash
this is the first comment
This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
Vous devez maintenant ignorer la première ligne, en commençant par #!/bin/bash
, et commentez les troisième et quatrième lignes, mais pas la cinquième car cette ligne est déjà commentée.
Dans sed
, vous pouvez utiliser quelque chose comme ceci :
$ sed '3,6s/^[^#]/# &/g' test_script
#/usr/bin/env bash
# this is the first comment
# This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
Dans la commande ci-dessus, les opérations suivantes sont effectuées :
3,6s
définit une plage, de la ligne 3 à la ligne 6./^[^#]/
correspond à tout ce qui est un caractère et ne commence pas par un dièse (#
)./# &/g
remplace une pièce, dans ce cas il met un#
devant la ligne dictée par le&
signer.
Exemple :Supprimer tous les chiffres
Différentes applications génèrent des données dans différents formats. Avec sed
, vous ne pouvez conserver que les données que vous pouvez utiliser. Par exemple, vous avez le fichier suivant (inputfile3
) dans ce format :
foo1234
bar99128
baz2842
qux12953
discard39120
Peut-être qu'un programme a généré le mauvais format, ou il a concaténé les champs en un seul. Que se passe-t-il si vous souhaitez uniquement conserver les caractères alphabétiques et supprimer les chiffres ? Comment atteindrez-vous cet objectif avec sed
? ?
La réponse est probablement plus simple que vous ne le pensez :
$ sed 's/\([a-z]*\).*/\1/' inputfile3
foo
bar
baz
qux
discard
Exemple :Modifier des lignes spécifiques
De plus, sed
peut également gérer les plages par modèle, ce qui signifie que vous pouvez spécifier un début et une fin chaîne et manipuler la plage. Par exemple :
$ cat inputfile4
hello world
start of the comment
another comment
end of a comment
dont comment this line
nor this line
Le sed
suivant la commande commentera les lignes commençant par start et se terminant par fin :
$ sed '/start/,/end/ s/^/# /' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
Débarrassez-vous également des lignes vides.
$ sed '/start/,/end/ s/^/# /;/^$/d' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
Il y a bien plus à sed
et ses riches fonctionnalités. Pour pouvoir utiliser pleinement sed
, veuillez consulter sa page de documentation, que vous pouvez trouver ici. Aussi, une excellente source d'informations sur sed
peut être trouvé ici.
Conclusion
Comme je l'ai couvert précédemment, vous utiliserez grep
lorsque vous souhaitez rechercher un motif, soit dans un fichier, soit dans plusieurs répertoires de manière récursive. Utilisez sed
si vous recevez des données d'un pipeline ou si vous souhaitez manipuler des données à la volée.
Le sed
La commande est scriptée et il est facile d'apprendre à effectuer des opérations de base. Tout ce dont vous avez besoin est de la pratique, en particulier avec les expressions régulières.