Lorsque vous travaillez avec des fichiers texte, vous devrez souvent rechercher et remplacer des chaînes de texte dans un ou plusieurs fichiers.
sed est un s streamer ed itor. Il peut effectuer une manipulation de texte de base sur des fichiers et des flux d'entrée tels que des pipelines. Avec sed , vous pouvez rechercher, trouver et remplacer, insérer et supprimer des mots et des lignes. Il prend en charge les expressions régulières de base et étendues qui vous permettent de faire correspondre des modèles complexes.
Dans cet article, nous verrons comment rechercher et remplacer des chaînes avec sed . Nous vous montrerons également comment effectuer une recherche et un remplacement récursifs.
Rechercher et remplacer la chaîne par sed #
Il existe plusieurs versions de sed , avec quelques différences fonctionnelles entre eux. macOS utilise la version BSD, tandis que la plupart des distributions Linux sont livrées avec GNU sed pré-installé par défaut. Nous utiliserons la version GNU.
La forme générale de recherche et de remplacement de texte à l'aide de sed prend la forme suivante :
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
-i- Par défaut,sedécrit sa sortie sur la sortie standard. Cette option indique àsedpour modifier les fichiers en place. Si une extension est fournie (ex -i.bak), une sauvegarde du fichier d'origine est créée.s- La commande de substitution, probablement la commande la plus utilisée dans sed./ / /- Caractère délimiteur. Il peut s'agir de n'importe quel caractère, mais généralement de la barre oblique (/) est utilisé.SEARCH_REGEX- Chaîne normale ou expression régulière à rechercher.REPLACEMENT- La chaîne de remplacement.g- Drapeau de remplacement global. Par défaut,sedlit le fichier ligne par ligne et ne change que la première occurrence duSEARCH_REGEXsur une ligne. Lorsque l'indicateur de remplacement est fourni, toutes les occurrences sont remplacées.INPUTFILE- Le nom du fichier sur lequel vous souhaitez exécuter la commande.
C'est une bonne pratique de mettre des guillemets autour de l'argument afin que les méta-caractères du shell ne se développent pas.
Voyons comment nous pouvons utiliser le sed commande pour rechercher et remplacer du texte dans des fichiers avec certaines de ses options et drapeaux les plus couramment utilisés.
À des fins de démonstration, nous utiliserons le fichier suivant :
file.txt123 Foo foo foo
foo /bin/bash Ubuntu foobar 456
Si le g flag est omis, seule la première instance de la chaîne de recherche dans chaque ligne est remplacée :
sed -i 's/foo/linux/' file.txt 123 Foo linux foo
linux /bin/bash Ubuntu foobar 456
Avec le drapeau de remplacement global sed remplace toutes les occurrences du modèle de recherche :
sed -i 's/foo/linux/g' file.txt 123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456
Comme vous l'avez peut-être remarqué, la sous-chaîne foo à l'intérieur du foobar string est également remplacé dans l'exemple précédent. Si ce n'est pas le comportement souhaité, utilisez l'expression de limite de mot (\b ) aux deux extrémités de la chaîne de recherche. Cela garantit que les mots partiels ne correspondent pas.
sed -i 's/\bfoo\b/linux/g' file.txt 123 Foo linux linux
linux /bin/bash Ubuntu foobar 456
Pour rendre le modèle de correspondance insensible à la casse, utilisez le I drapeau. Dans l'exemple ci-dessous, nous utilisons à la fois le g et I drapeaux :
sed -i 's/foo/linux/gI' file.txt 123 linux linux linux
linux /bin/bash Ubuntu linuxbar 456
Si vous souhaitez rechercher et remplacer une chaîne contenant le caractère délimiteur (/ ) vous devrez utiliser la barre oblique inverse (\ ) pour échapper à la barre oblique. Par exemple pour remplacer /bin/bash avec /usr/bin/zsh vous utiliseriez
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt
L'option la plus simple et la plus lisible consiste à utiliser un autre caractère délimiteur. La plupart des gens utilisent la barre verticale (| ) ou deux-points (: ) mais vous pouvez utiliser n'importe quel autre caractère :
sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt 123 Foo foo foo
foo /usr/bin/zsh Ubuntu foobar 456
Vous pouvez également utiliser des expressions régulières. Par exemple, pour rechercher tous les nombres à 3 chiffres et les remplacer par la chaîne number vous utiliseriez :
sed -i 's/\b[0-9]\{3\}\b/number/g' file.txt
number Foo foo foo
foo /bin/bash demo foobar number
Une autre fonctionnalité utile de sed est que vous pouvez utiliser le caractère esperluette & qui correspond au motif correspondant. Le personnage peut être utilisé plusieurs fois.
Par exemple, si vous souhaitez ajouter des accolades {} autour de chaque nombre à 3 chiffres, tapez :
sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txt
{123} Foo foo foo
foo /bin/bash demo foobar {456}
Enfin, c'est toujours une bonne idée de faire une sauvegarde lors de l'édition d'un fichier avec sed . Pour ce faire, il suffit de fournir une extension pour le fichier de sauvegarde au -i option. Par exemple, pour éditer le file.txt et enregistrez le fichier d'origine sous file.txt.bak vous utiliseriez :
sed -i.bak 's/foo/linux/g' file.txt
Pour vous assurer que la sauvegarde est créée, listez les fichiers avec le ls commande :
ls file.txt file.txt.bak
Recherche et remplacement récursifs #
Parfois, vous souhaiterez peut-être rechercher de manière récursive des répertoires pour les fichiers contenant une chaîne et remplacer la chaîne dans tous les fichiers. Cela peut être fait en utilisant des commandes telles que find ou grep pour rechercher récursivement des fichiers dans le répertoire et diriger les noms de fichiers vers sed .
La commande suivante recherchera récursivement les fichiers dans le répertoire de travail actuel et transmettra les noms de fichiers à sed .
find . -type f -exec sed -i 's/foo/bar/g' {} +
Pour éviter les problèmes avec les fichiers contenant des espaces dans leurs noms, utilisez le -print0 option, qui indique find pour imprimer le nom du fichier, suivi d'un caractère nul et diriger la sortie vers sed en utilisant xargs -0 :
find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'
Pour exclure un répertoire, utilisez le -not -path option. Par exemple, si vous remplacez une chaîne dans votre référentiel git local pour exclure tous les fichiers commençant par un point (. ), utilisez :
find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g' Si vous souhaitez rechercher et remplacer du texte uniquement sur des fichiers avec une extension spécifique, vous utiliserez :
find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'
Une autre option consiste à utiliser le grep commande pour rechercher de manière récursive tous les fichiers contenant le modèle de recherche, puis diriger les noms de fichiers vers sed :
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g' Conclusion #
Bien que cela puisse sembler compliqué et complexe, au début, rechercher et remplacer du texte dans des fichiers avec sed est très simple.
Pour en savoir plus sur sed commandes, options et drapeaux, consultez le manuel GNU sed et le didacticiel Grymoire sed.
Si vous avez des questions ou des commentaires, n'hésitez pas à laisser un commentaire.