web-dev-qa-db-fra.com

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

Comment trouver et remplacer des mots spécifiques dans un fichier texte à l'aide de la ligne de commande?

595
Jon Doe
sed -i 's/original/new/g' file.txt

Explication:

  • sed = Editeur de flux
  • -i = in-situ (c'est-à-dire sauvegarder dans le fichier d'origine)
  • La chaîne de commande:

    • s = la commande de substitution
    • original = une expression rationnelle décrivant le mot à remplacer (ou simplement le mot lui-même)
    • new = le texte avec lequel le remplacer
    • g = global (c'est-à-dire tout remplacer et pas seulement la première occurrence)
  • file.txt = le nom du fichier

967
cscarney

Il y a différentes façons de le faire. On utilise sed et Regex. SED est un éditeur de flux permettant de filtrer et de transformer du texte. Un exemple est le suivant:

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 manière qui peut avoir plus de sens que < strin et > strout est d'utiliser des pipes!

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
30
Marco Ceppi

Grâce à la commande gsub de 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 remplacer une colonne en particulier, 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.

À travers Perl,

$ echo 'foo' | Perl -pe 's/foo/bar/g'
bar
20
Avinash Raj

Vous pouvez utiliser Vim en mode Ex:

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

  2. s substitute

  3. g remplace toutes les instances de chaque ligne

  4. x écrire si des modifications ont été apportées (ils l’ont fait) et quitter

20
Steven Penny

Il y a une multitude de façons de le réaliser. En fonction de la complexité de l'objectif recherché avec le remplacement de chaîne et des outils connus de l'utilisateur, certaines méthodes peuvent être préférées à d'autres.

Dans cette réponse, j'utilise un simple fichier 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 destiné au traitement de texte, mais de simples substitutions peuvent être effectuées via expansion des paramètres , en particulier nous pouvons utiliser 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 script ne fait pas de remplacement sur place, ce qui signifie que vous devez enregistrer le 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 en gros la façon dont Shell lit les fichiers ligne par ligne. Voir this pour référence.

AWK

AWK, étant un utilitaire de traitement de texte, convient parfaitement à cette tâche. Il peut faire des remplacements simples et beaucoup plus avancés basés sur expressions régulières . Il fournit deux fonctions: sub() et gsub(). Le premier ne remplace que la première occurrence, tandis que le second - remplace les occurrences dans la chaîne entière. Par exemple, si nous avons la chaîne one potato two potato, le résultat serait:

$ 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. Il serait donc facile de faire la même chose avec input.txt:

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

Selon la version d'AWK que vous possédez, il est possible que l'édition in-situ ne soit pas activée. Par conséquent, la pratique habituelle consiste à enregistrer et 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 de simples substitutions, il suffit de faire:

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

L'avantage de cet outil est qu'il dispose d'une édition sur place, que vous pouvez activer avec l'indicateur -i.

Perl

Perl est un autre outil souvent utilisé pour le traitement de texte, mais il s’agit d’un langage généraliste utilisé dans les réseaux, l’administration système, les applications de bureau, etc. Il a emprunté beaucoup de concepts/fonctionnalités d'autres langages tels que C, sed, awk et autres. La substitution simple peut être faite comme suit:

Perl -pe 's/blue/Azure/' input.txt

Comme sed, Perl a également le drapeau -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", vous pourriez faire var.replace("Hello","Good Morning")

Un moyen simple de lire le fichier et de remplacer la chaîne est le suivant:

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

Cependant, avec Python, vous devez également générer le nouveau fichier, ce que vous pouvez également créer à partir du script lui-même. Par exemple, voici un exemple 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 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 façon, assurez-vous qu’il est défini comme exécutable avec chmod +x ./myscript.py

Python peut également avoir des expressions régulières, notamment le module re, qui possède la fonction re.sub(), qui peut être utilisée pour des remplacements plus avancés.

18
Sergiy Kolodyazhnyy

sedest la chaîne s ed , en ce sens que vous pouvez utiliser | (pipe) pour envoyer des flux standard (STDIN et STDOUT spécifiquement) via sedet les modifier par programmation à la volée, ce qui en fait un outil pratique dans Unix tradition philosophique; mais peut aussi éditer directement des fichiers, en utilisant le paramètre -i mentionné ci-dessous.
Considérez ce qui suit :

sed -i -e 's/few/asd/g' hello.txt

s/ est utilisé pour s ubstitute l'expression trouvée fewavec asdname__:

Les rares, les courageux.


Les asd, les braves.

/g signifie "global", ce qui signifie le faire pour toute la ligne. Si vous laissez le /g (avec s/few/asd/, il doit toujours y avoir trois barres obliques quoi qu'il en soit) et que fewapparaisse deux fois sur la même ligne, seul le premier fewest remplacé par asdname__:

Les rares hommes, les rares femmes, les braves.


Les hommes, les rares femmes, les braves.

Ceci est utile dans certaines circonstances, comme modifier des caractères spéciaux au début des lignes (par exemple, remplacer les symboles plus grands que certaines personnes utilisent pour citer le contenu précédent dans les fils de courrier électronique avec un onglet horizontal tout en laissant une inégalité algébrique citée plus tard dans la ligne. inaltéré), mais dans votre exemple où vous spécifiez que n'importe où fewdoit être remplacé, assurez-vous que vous avez bien ce /g.

Les deux options suivantes (drapeaux) sont combinées en une seule, -ie:

L'option -i permet d'éditer i n place sur le fichier hello.txt.

L'option -e indique que la commande e est exécutée, dans ce cas, s/.

Remarque: Il est important que vous utilisiez -i -e pour rechercher/remplacer. Si vous faites -ie, vous créez une sauvegarde de chaque fichier avec la lettre 'e' ajoutée.

8
Chaminda Bandara

Vous pouvez 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', os.getcwd ()] dans tous les fichiers résultant de la commande de localisation, 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 le fichier à rechercher

2
Nguyễn Tuấn Anh