GNU/Linux >> Tutoriels Linux >  >> Linux

Comment utiliser sed pour rechercher et remplacer une chaîne dans des fichiers

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 à sed pour 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, sed lit le fichier ligne par ligne et ne change que la première occurrence du SEARCH_REGEX sur 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.txt
123 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.


Linux
  1. Comment utiliser FIND sous Linux

  2. Comment trouver des fichiers avec des autorisations SUID et SGID sous Linux

  3. Comment remplacer une chaîne dans un ou plusieurs fichiers ?

  4. Comment utiliser Sed pour remplacer une chaîne multiligne ?

  5. Utiliser grep et sed pour rechercher et remplacer une chaîne

Comment trouver une chaîne ou un mot spécifique dans les fichiers et les répertoires

Comment utiliser les commandes de recherche et de localisation sous Linux :Guide du débutant

Comment rechercher et supprimer des fichiers en double sous Linux

Comment utiliser la commande SED pour rechercher et remplacer une chaîne dans des fichiers

Comment trouver des fichiers en double sous Linux et les supprimer

Comment utiliser Sed pour rechercher et remplacer une chaîne dans un fichier