858 votes

Rechercher et remplacer du texte dans un fichier à l'aide de commandes

Comment trouver et remplacer des mots spécifiques dans un fichier texte en utilisant la ligne de commande ?

1386voto

Adam Haile Points 12576
sed -i 's/original/new/g' file.txt

Explication :

  • sed = Stream EDitor
  • -i = sur place (c'est-à-dire sauvegarder dans le fichier d'origine)
  • La chaîne de commande :

    • s = la commande de substitution
    • original = une expression régulière décrivant le mot à remplacer (ou juste le mot lui-même)
    • new = le texte à remplacer par
    • g = global (c'est-à-dire remplacer toutes les occurrences et pas seulement la première)
  • file.txt = le nom du fichier

0 votes

Comment incorporer les regex à ce système ?

3 votes

@Akiva Si vous incluez caractères spéciaux de regex dans votre recherche sed leur correspondra. Ajoutez un -r si vous souhaitez plutôt utiliser des RE étendus.

1 votes

Puis-je utiliser la commande "sed -i" lorsque les chaînes "original" et "nouveau" contiennent des caractères spéciaux comme "/" ou similaires ?

62voto

Sergiy Kolodyazhnyy Points 97292

Il y a une multitude de façons d'y parvenir. Selon la complexité de ce que l'on cherche à réaliser avec le remplacement de chaînes de caractères, et selon les outils avec lesquels l'utilisateur est familier, certaines méthodes peuvent être préférées à d'autres.

Dans cette réponse, j'utilise un simple input.txt que vous pouvez utiliser pour tester tous les exemples fournis ici. Le contenu du fichier :

roses are red , violets are blue
This is an input.txt and this doesn't rhyme

BASH

Bash n'est pas vraiment conçu pour le traitement de texte, mais des substitutions simples peuvent être effectuées via la fonction expansion des paramètres En particulier, nous pouvons utiliser ici une structure simple ${parameter/old_string/new_string} .

#!/bin/bash
while IFS= read -r line
do
    case "$line" in
       *blue*) printf "%s\n" "${line/blue/azure}" ;;
       *) printf "%s\n" "$line" ;;
    esac
done < input.txt

Ce petit ne fait pas de remplacement en place, ce qui signifie que vous devriez enregistrer le nouveau texte dans un nouveau fichier, et vous débarrasser de l'ancien fichier, ou bien mv new.txt old.txt

Remarque : si vous êtes curieux de savoir pourquoi while IFS= read -r ; do ... done < input.txt est utilisé, c'est en fait la façon dont Shell lit le fichier ligne par ligne. Voir ce pour référence.

AWK

AWK, étant un utilitaire de traitement de texte, est tout à fait approprié pour une telle tâche. Il peut effectuer des remplacements simples et des remplacements beaucoup plus avancés basés sur les principes suivants expressions régulières . Il assure deux fonctions : sub() y gsub() . La première remplace uniquement la première occurrence, tandis que la seconde remplace les occurrences de toute la chaîne. Par exemple, si nous avons la chaîne one potato two potato le résultat serait le suivant :

$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana

$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'                                      
one banana two potato 

AWK peut prendre un fichier d'entrée comme argument, donc faire les mêmes choses avec input.txt Ce serait facile :

awk '{sub(/blue/,"azure")}1' input.txt

En fonction de la version de AWK que vous avez, il se peut qu'il n'y ait pas d'édition en place, donc la pratique habituelle est d'enregistrer et de remplacer le nouveau texte. Par exemple, quelque chose comme ceci :

awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt

SED

Sed est un éditeur de ligne. Il utilise également les expressions régulières, mais pour de simples substitutions, il suffit de le faire :

sed 's/blue/azure/' input.txt

Ce qui est bien avec cet outil, c'est qu'il dispose d'une fonction d'édition sur place, que vous pouvez activer avec le bouton -i drapeau.

Perl

Perl est un autre outil souvent utilisé pour le traitement de texte, mais c'est un langage à usage général, et il est utilisé dans les réseaux, l'administration système, les applications de bureau, et bien d'autres endroits. Il a emprunté beaucoup de concepts/caractéristiques à d'autres langages tels que C, sed, awk, et d'autres. Une simple substitution peut être effectuée comme suit :

perl -pe 's/blue/azure/' input.txt

Comme sed, perl possède également l'option -i.

Python

Ce langage est très polyvalent et est également utilisé dans une grande variété d'applications. Il dispose d'un grand nombre de fonctions pour travailler avec des chaînes de caractères, notamment replace() donc si vous avez une variable comme var="Hello World" vous pourriez faire var.replace("Hello","Good Morning")

Une façon simple de lire un fichier et d'y remplacer une chaîne de caractères serait la suivante :

python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt

Avec Python, cependant, vous devez également sortir vers un nouveau fichier , ce que vous pouvez également faire à partir du lui-même. Par exemple, en voici un simple :

#!/usr/bin/env python
import sys
import os
import tempfile

tmp=tempfile.mkstemp()

with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
    for line in fd1:
        line = line.replace('blue','azure')
        fd2.write(line)

os.rename(tmp[1],sys.argv[1])

Ce script doit être appelé avec input.txt comme argument de ligne de commande. La commande exacte pour exécuter le script Python avec l'argument de la ligne de commande serait la suivante

 $ ./myscript.py input.txt

o

$ python ./myscript.py input.txt

Bien sûr, assurez-vous que ./myscript.py se trouve dans votre répertoire de travail actuel et pour la première façon, assurez-vous qu'il est défini comme exécutable avec chmod +x ./myscript.py

Python peut également utiliser des expressions régulières, en particulier, il y a re qui a re.sub() qui peut être utilisée pour des remplacements plus avancés.

1 votes

Belle compilation ! Un autre moyen possible, non mentionné ici, est d'utiliser la fonction tr dans unix

1 votes

@TapajitDey Oui, tr est un autre outil formidable, mais notez qu'il sert à remplacer des ensembles de caractères ( par exemple tr abc cde traduirait a a c , b a d . C'est un peu différent de remplacer des mots entiers comme avec sed o python

37voto

Redbaron Points 523

Il existe un certain nombre de façons différentes de procéder. La première consiste à utiliser sed et Regex. SED est un éditeur de flux qui permet de filtrer et de transformer du texte. Voici un exemple :

marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog

Une autre façon, qui peut être plus logique que < strin y > strout est avec des tuyaux !

marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai 
The quick brown fox jumped over the lazy sleeping dog

6 votes

Noter le cat en cat file | sed '...' n'est pas nécessaire. Vous pouvez dire directement sed '...' file .

1 votes

En effet, il est possible de réduire encore davantage cette situation : sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly va prendre le fichier yarly et faire les 2 changements en place tout en faisant une sauvegarde. Utilisation de time bash -c "$COMMAND" à la fois il suggère que cette version est un ~5 fois plus rapide.

23voto

Zombo Points 1663

Vous pouvez utiliser Vim en mode Ex :

ex -s -c '%s/OLD/NEW/g|x' file
  1. % sélectionner toutes les lignes

  2. s substitut

  3. g remplacer toutes les instances dans chaque ligne

  4. x écrire si des changements ont été faits (c'est le cas) et sortir.

22voto

Avinash Raj Points 72686

Grâce à la commande gsub de l'awk,

awk '{gsub(/pattern/,"replacement")}' file

Exemple :

awk '{gsub(/1/,"0");}' file

Dans l'exemple ci-dessus, tous les 1 sont remplacés par des 0, quelle que soit la colonne où ils se trouvent.


Si vous voulez faire un remplacement sur une colonne spécifique, alors faites comme ceci,

awk '{gsub(/pattern/,"replacement",column_number)}' file

Exemple :

awk '{gsub(/1/,"0",$1);}' file

Il remplace le 1 par le 0 sur la première colonne uniquement.

Par Perl,

$ echo 'foo' | perl -pe 's/foo/bar/g'
bar

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X