Comment puis-je trouver et remplacer des mots spécifiques dans un fichier texte à l'aide de la ligne de commande?
sed -i 's/original/new/g' file.txt
Explication:
-
sed
= Éditeur de flux -
-i
= en 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 pour le remplacer par -
g
= global (c'est-à-dire remplacer tout et pas seulement la première occurrence)
-
file.txt
= le nom du fichier
Il y a une multitude de façons d'y parvenir. Selon la complexité de ce que l'on essaie de réaliser avec le remplacement de chaîne, et selon les outils avec lesquels l'utilisateur est familier, certaines méthodes peuvent être préférées plus que d'autres.
Dans cette réponse, j'utilise simple input.txt
fichier, que vous pouvez utiliser pour tester tous les exemples fournis ici. Le contenu du fichier:
roses are red , violets are blueThis is an input.txt and this doesn't rhyme
BASH
Bash n'est pas vraiment destiné au traitement de texte, mais de simples substitutions peuvent être effectuées via expansion des paramètres , en particulier ici, nous pouvons utiliser une structure simple ${parameter/old_string/new_string}
.
#!/bin/bashwhile IFS= read -r linedo case "$line" in *blue*) printf "%s\n" "${line/blue/azure}" ;; *) printf "%s\n" "$line" ;; esacdone < input.txt
Ce petit script ne remplace pas sur place, ce qui signifie que vous devrez enregistrer un nouveau texte dans un nouveau fichier et vous débarrasser de l'ancien fichier, ou mv new.txt old.txt
Note latérale: si vous êtes curieux de savoir pourquoi while IFS= read -r ; do ... done < input.txt
est utilisé, c'est essentiellement 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 expressions régulières. Il fournit deux fonctions: sub()
et gsub()
. La première ne remplace que la première occurrence, tandis que la seconde remplace les occurrences dans une chaîne entière. Par exemple, si nous avons une chaîne one potato two potato
, ce serait le résultat:
$ 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
Selon la version d'AWK que vous avez, il peut ou non avoir une édition sur place, d'où la pratique habituelle est de sauvegarder 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 des expressions régulières, mais pour des substitutions simples, il suffit de faire:
sed 's/blue/azure/' input.txt
Ce qui est bien avec cet outil, c'est qu'il a une édition sur place, que vous pouvez activer avec -i
drapeau.
Perl
Perl est un autre outil souvent utilisé pour le traitement de texte, mais c'est un langage à usage général, utilisé dans les réseaux, l'administration système, les applications de bureau et bien d'autres endroits. Il a emprunté beaucoup de concepts/fonctionnalités à d'autres langages tels que C,sed,awk et autres. Une simple substitution peut être effectuée comme suit:
perl -pe 's/blue/azure/' input.txt
Comme sed, perl a aussi l'indicateur-i.
Python
Ce langage est très polyvalent et est également utilisé dans une grande variété d'applications. Il a beaucoup de fonctions pour travailler avec des chaînes, parmi lesquelles replace()
, donc si vous avez une variable comme var="Hello World"
, tu pourrais faire var.replace("Hello","Good Morning")
Un moyen simple de lire le fichier et de remplacer la chaîne serait le suivant:
python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt
Avec Python, cependant , vous devez également générer un nouveau fichier, ce que vous pouvez également faire à partir du script lui-même. Par exemple, en voici un simple:
#!/usr/bin/env pythonimport sysimport osimport tempfiletmp=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 un script python avec un argument de ligne de commande serait
$ ./myscript.py input.txt
ou
$ python ./myscript.py input.txt
Bien sûr, assurez-vous que ./myscript.py
est dans votre répertoire de travail actuel et pour la première fois, assurez-vous qu'il est défini exécutable avec chmod +x ./myscript.py
Python peut aussi avoir des expressions régulières, en particulier, il y a re
module, qui a re.sub()
fonction, qui peut être utilisée pour des remplacements plus avancés.
Il y a un certain nombre de façons différentes de le faire. On utilise sed
et Regex. SED est un éditeur de flux pour filtrer et transformer du texte. Un exemple est le suivant:
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orlymarco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarlymarco@imacs-suck: ~$ cat yarlyThe quick brown unicorn jumped over the hyper sleeping dog
Une autre façon qui peut avoir plus de sens que < strin
et > strout
c'est avec des pipes!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowaimarco@imacs-suck: ~$ cat nowai The quick brown fox jumped over the lazy sleeping dog
Via la commande gsub d'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ù il se trouve.
Si vous souhaitez effectuer un remplacement sur une colonne spécifique, procédez comme suit,
awk '{gsub(/pattern/,"replacement",column_number)}' file
Exemple:
awk '{gsub(/1/,"0",$1);}' file
Il remplace 1 par 0 sur la première colonne uniquement.
Par Perl,
$ echo 'foo' | perl -pe 's/foo/bar/g'bar
Vous pouvez utiliser Vim en mode Ex:
ex -s -c '%s/OLD/NEW/g|x' file
%
sélectionnez toutes les ligness
remplacerg
remplacer toutes les instances de chaque lignex
écrivez si des modifications ont été apportées (elles l'ont été) et quittez
sed
est le stream Editor, en ce que vous pouvez utiliser |
(pipe) à envoyer flux standard (STDIN et STDOUT spécifiquement) à travers sed
et les modifier par programme à la volée, ce qui en fait un outil pratique dans la tradition de la philosophie Unix; mais peut également éditer des fichiers directement, en utilisant le -i
paramètre mentionné ci-dessous.
Considérez ce qui suit:
sed -i -e 's/few/asd/g' hello.txt
s/
est utilisé pour ssubstituer l'expression trouvée few
avec asd
:
Les quelques-uns, les courageux.
Les TSA, les courageux.
/g
signifie "global", ce qui signifie le faire pour toute la ligne. Si vous laissez de côté le /g
(avec s/few/asd/
, il doit toujours y avoir trois barres obliques quoi qu'il arrive) et few
apparaît deux fois sur la même ligne, seulement la première few
est changé en asd
:
Les quelques hommes, les quelques femmes, les braves.
Les hommes TSA, les quelques femmes, les courageux.
Ceci est utile dans certaines circonstances, comme la modification de caractères spéciaux au début des lignes (par exemple, le remplacement des symboles supérieurs à ceux que certaines personnes utilisent pour citer le matériel précédent dans les fils de discussion d'e-mail par une tabulation horizontale tout en laissant une inégalité algébrique citée plus loin dans la ligne intacte), mais dans votre exemple où vous spécifiez que partout few
s'il doit être remplacé, assurez-vous que vous l'avez /g
.
Les deux options suivantes (drapeaux) sont combinées en une seule, -ie
:
-i
l'option est utilisée pour modifier in place sur le fichier hello.txt
.
-e
l'option indique le expression / commande à exécuter, dans ce cas s/
.
Remarque: Il est important que vous utilisiez -i -e
pour rechercher / remplacer. Si tu le fais -ie
, vous créez une sauvegarde de chaque fichier avec la lettre " e " ajoutée.
Tu peux faire comme ça:
locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g"
Exemples: pour remplacer toutes les occurrences [logdir',"] (sans []) par [logdir',".getcwd ()] dans tous les fichiers qui sont le résultat de la commande locate, faites:
ex1:
locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"
ex2:
locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"
où [tensorboard/program.py] est un fichier à rechercher