Question 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?


434
2018-01-07 04:10


origine


De votre intérêt github.com/lucio-martinez/rch :-) - Lucio


Réponses:


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

Explication:

  • sed = Éditeur de flux
  • -i = sur place (c.-à-d. 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 simplement 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


724
2018-01-07 04:23



@mcExchange Si c'est spécifiquement le / caractère que vous devez faire correspondre, vous pouvez simplement utiliser un autre caractère comme séparateur (par ex. 's_old/text_new/text_g'). Sinon, vous pouvez mettre un \  avant l'un des $ * . [ \ ^ pour obtenir le caractère littéral. - cscarney
@BrianZ En ce qui concerne le système de fichiers, la sortie de sed est un nouveau fichier du même nom. C'est l'un des bugs fréquemment rapportés qui ne sont pas des bugs - cscarney
Vous voudrez peut-être s/\boriginal\b/new/g au lieu de s/original/new/g (\b correspond à une limite de mot) pour ne remplacer que des mots entiers. - Chris Martin
La commande OSX sed -i '.bak' 's/original/new/g' file.txt peut également être exécuté avec une extension de longueur zéro sed -i '' 's/original/new/g' file.txt, qui ne générera aucune sauvegarde. - Kirk
Les utilisateurs de MacOS devront ajouter '' "après -i comme paramètre pour -i ed.gs/2016/01/26/os-x-sed-invalid-command-code pour que le fichier soit écrasé. - geoyws


Il y a un certain nombre de manières différentes de le faire. On utilise sed et Regex. SED est un éditeur de flux pour filtrer et transformer le 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 façon qui peut avoir plus de sens que < strin et > strout est avec 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

26
2018-01-07 04:26



noter la cat dans cat file | sed '...' est inutile. Vous pouvez dire directement sed '...' file. - fedorqui
En effet, cela peut être réduit davantage: sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly va prendre fichier et faire les 2 changements en place tout en faisant une sauvegarde. En utilisant time bash -c "$COMMAND" au temps, cela suggère que cette version est environ 5 fois plus rapide. - pbhj


Vous pouvez utiliser Vim en mode Ex:

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

  2. s remplacer

  3. g remplacer toutes les instances de chaque ligne

  4. x écrire si des modifications ont été apportées (elles ont) et quitter


15
2018-04-16 18:36





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 0, quelle que soit la colonne où ils se trouvent.


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

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

Exemple:

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

Il remplace 1 par 0 sur la colonne 1 uniquement.

Par Perl,

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

14
2017-07-02 12:59



Je l'ai utilisé sur le terminal MacOS et ça n'a rien fait ... - Jim


Il y a une multitude de façons d'y parvenir. Selon la complexité de ce que l'on essaie d'obtenir 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 blue
This is an input.txt and this doesn't rhyme

FRAPPER

Bash n'est pas vraiment destiné au traitement de texte, mais des substitutions simples peuvent être effectuées via extension des paramètres , en particulier ici, 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 supprimer l’ancien fichier, ou mv new.txt old.txt

Note: si vous êtes curieux de savoir pourquoi while IFS= read -r ; do ... done < input.txt est utilisé, il s'agit essentiellement de la manière du shell de lire 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 faire des remplacements simples et beaucoup plus avancés basés sur expressions régulières. Il offre deux fonctions: sub() et gsub(). Le premier ne remplace que la première occurrence, tandis que le second - remplace les occurrences dans une chaîne complète. 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 serait facile:

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

Selon la version de AWK que vous avez, il peut ou non avoir une édition sur place, la pratique habituelle est donc 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 comporte 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 il s’agit d’un langage général, utilisé dans la mise en réseau, 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. La substitution simple peut être faite comme suit:

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

Comme sed, perl a aussi 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 un fichier et de remplacer une chaîne est 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, que vous pouvez également utiliser depuis le script lui-même. Par exemple, 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.

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é pour des remplacements plus avancés.


12
2018-02-03 07:49





sed est le stream editor, en ce que vous pouvez utiliser | (pipe) pour envoyer flux standard (STDIN et STDOUT spécifiquement) à travers sed et les modifier à la volée, ce qui en fait un outil pratique dans la tradition philosophique Unix; mais peut éditer des fichiers directement aussi, en utilisant le -i paramètre mentionné ci-dessous.
Considérer ce qui suit:

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

s/ est utilisé pour sremplacer l'expression trouvée few avec asd:

Les rares, les braves.


La cendre, le brave.

/g signifie "global", ce qui signifie faire cela pour toute la ligne. Si vous laissez la /g (avec s/few/asd/, il doit toujours y avoir trois barres obliques, peu importe quoi) et few apparaît deux fois sur la même ligne, seule la première few est changé pour asd:

Les quelques hommes, les quelques femmes, les braves.


Les hommes asd, les rares femmes, les braves.

Ceci est utile dans certaines circonstances, comme la modification de caractères spéciaux au début des lignes (par exemple, remplacer les symboles plus grands que ceux que certaines personnes utilisent pour citer le matériel précédent dans les fils de messagerie avec une tabulation horizontale tout en laissant une inégalité algébrique plus tard dans la ligne) intacte), mais dans votre exemple où vous spécifiez que nulle part  few se produit il devrait être remplacé, assurez-vous que vous avez /g.

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

-i l'option est utilisée pour éditer jen place sur le fichier hello.txt.

-e option indique le expression / commande à exécuter, dans ce cas s/.

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


6
2017-11-23 09:00





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 []) avec [logdir', os.getcwd ()] dans tous les fichiers résultant de la commande de localisation, faites:

locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"

où [tensorboard / program.py] est un fichier à rechercher


0
2017-07-24 02:13



Salut. Votre choix de chaînes (logdir', '' -> /logdir', os.getcwd()) rend cette réponse difficile à analyser. En outre, il convient de préciser que votre réponse recherche d'abord les fichiers à utiliser, car cela ne fait pas partie de la question. - mwfearnley
Salut, cette réponse est à la fois la recherche et tout remplacer si elle a trouvé <ancien texte> dans le fichier. - Nguyễn Tuấn Anh
Je choisis cette réponse pour tout ce qu'ils utilisent tensorboard dans keras, qui veulent changer la commande de: tensorboard --logdir = '/ path / à / log / folder /' pour utiliser: tensorboard uniquement, en restant dans le dossier logs. c'est très pratique - Nguyễn Tuấn Anh