Suchen und Ersetzen von Text in einer Datei mithilfe von Befehlen

Wie kann ich bestimmte Wörter in einer Textdatei über die Befehlszeile suchen und ersetzen?

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

Erklärung:

  • sed = Streameditor
  • -i = in-place (dh zurück in die Originaldatei speichern)
  • Die Befehlszeichenfolge:

    • s = der Ersatzbefehl
    • original = ein regulärer Ausdruck, der das zu ersetzende Wort beschreibt (oder nur das Wort selbst)
    • new = der Text, durch den er ersetzt werden soll
    • g = global (dh alle ersetzen und nicht nur das erste Vorkommen)
  • file.txt = der Dateiname

Es gibt eine Vielzahl von Möglichkeiten, dies zu erreichen. Abhängig von der Komplexität dessen, was mit dem Ersetzen von Zeichenfolgen erreicht werden soll, und abhängig von den Tools, mit denen der Benutzer vertraut ist, werden einige Methoden möglicherweise mehr bevorzugt als andere.

In dieser Antwort verwende ich einfach input.txt datei, mit der Sie alle hier bereitgestellten Beispiele testen können. Dateiinhalte:

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

BASH

Bash ist nicht wirklich für die Textverarbeitung gedacht, aber einfache Ersetzungen können über erfolgen parametererweiterung , insbesondere hier können wir einfache Struktur verwenden ${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

Dieses kleine Skript ersetzt nicht direkt, was bedeutet, dass Sie neuen Text in einer neuen Datei speichern und die alte Datei entfernen müssten, oder mv new.txt old.txt

Randnotiz: wenn Sie neugierig sind, warum while IFS= read -r ; do ... done < input.txt wird, ist es im Grunde die Art und Weise, wie Shell Dateien Zeile für Zeile liest. Sehen dieser als Referenz.

AWK

AWK, ein Textverarbeitungsprogramm, ist für eine solche Aufgabe durchaus geeignet. Es kann einfache und viel fortgeschrittenere Ersetzungen durchführen, basierend auf reguläre Ausdrücke. Es bietet zwei Funktionen: sub() und gsub(). Der erste ersetzt nur das erste Vorkommen, während der zweite Vorkommen in der gesamten Zeichenfolge ersetzt. Zum Beispiel, wenn wir string haben one potato two potato , dies wäre das Ergebnis:

$ 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 kann eine Eingabedatei als Argument verwenden, also dasselbe tun mit input.txt , wäre einfach:

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

Abhängig von der Version von AWK, die Sie haben, kann es eine direkte Bearbeitung geben oder nicht, daher ist es üblich, neuen Text zu speichern und zu ersetzen. Zum Beispiel so etwas:

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

SED

Sed ist ein Zeileneditor. Es werden auch reguläre Ausdrücke verwendet, aber für einfache Ersetzungen reicht es aus:

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

Das Gute an diesem Tool ist, dass es eine direkte Bearbeitung bietet, die Sie aktivieren können mit -i Flagge.

Perl

Perl ist ein weiteres Werkzeug, das häufig für die Textverarbeitung verwendet wird, aber es ist eine Allzwecksprache und wird in Netzwerken, Systemadministration, Desktop-Apps und vielen anderen Orten verwendet. Es hat viele Konzepte / Funktionen aus anderen Sprachen wie C, sed, awk und anderen ausgeliehen. Einfache Substitution kann so erfolgen:

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

Wie sed hat auch Perl das Flag -i .

Pythonschlange

Diese Sprache ist sehr vielseitig und wird auch in den unterschiedlichsten Anwendungen eingesetzt. Es hat viele Funktionen zum Arbeiten mit Strings, darunter replace(), also wenn Sie eine Variable wie haben var="Hello World" , könnten Sie tun var.replace("Hello","Good Morning")

Eine einfache Möglichkeit, eine Datei zu lesen und die Zeichenfolge darin zu ersetzen, wäre wie folgt:

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

Mit Python müssen Sie jedoch auch in eine neue Datei ausgeben, was Sie auch innerhalb des Skripts selbst tun können. Zum Beispiel, hier ist eine einfache:

#!/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])

Dieses Skript soll aufgerufen werden mit input.txt als Befehlszeilenargument. Der genaue Befehl zum Ausführen eines Python-Skripts mit Befehlszeilenargument wäre

 $ ./myscript.py input.txt

oder

$ python ./myscript.py input.txt

Stellen Sie natürlich sicher, dass ./myscript.py befindet sich in Ihrem aktuellen Arbeitsverzeichnis und stellen Sie für den ersten Weg sicher, dass es ausführbar ist mit chmod +x ./myscript.py

Python kann auch reguläre Ausdrücke haben, insbesondere gibt es re modul, das re.sub() funktion, die für fortgeschrittenere Ersetzungen verwendet werden kann.

Es gibt verschiedene Möglichkeiten, dies zu tun. Einer benutzt sed und Regex. SED ist ein Stream-Editor zum Filtern und Transformieren von Text. Ein Beispiel ist wie folgt:

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

Ein anderer Weg, der sinnvoller sein kann als < strin und > strout ist mit Pfeifen!

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

Über den Befehl gsub von awk,

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

Beispiel:

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

Im obigen Beispiel werden alle 1 durch 0 ersetzt, unabhängig von der Spalte, in der sie sich befindet.


Wenn Sie eine bestimmte Spalte ersetzen möchten, gehen Sie folgendermaßen vor,

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

Beispiel:

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

Es ersetzt 1 nur in der ersten Spalte durch 0.

Durch Perl,

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

Sie können Vim im Ex-Modus verwenden:

ex -s -c '%s/OLD/NEW/g|x' file
  1. % alle Zeilen auswählen

  2. s Ersatz

  3. g ersetzen Sie alle Instanzen in jeder Zeile

  4. x schreiben Sie, ob Änderungen vorgenommen wurden (sie haben) und beenden Sie

sed ist der stream editor, in dem Sie verwenden können | (rohr) zu senden standard-Streams (speziell STDIN und STDOUT) durch sed und ändern Sie sie programmgesteuert im laufenden Betrieb, was es zu einem praktischen Werkzeug in der Unix-Philosophietradition macht; kann aber auch Dateien direkt bearbeiten, indem man die -i parameter unten erwähnt.
Betrachten Sie Folgendes:

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

s/ wird verwendet, um sersetzen Sie den gefundenen Ausdruck few mit asd:

Die wenigen, die Mutigen.


Der asd, der Mutige.

/g steht für "global", was bedeutet, dies für die gesamte Zeile zu tun. Wenn Sie die /g (mit s/few/asd/, es müssen immer drei Schrägstriche sein, egal was passiert) und few erscheint zweimal in derselben Zeile, nur die erste few wird geändert in asd:

Die wenigen Männer, die wenigen Frauen, die Tapferen.


Die ASD-Männer, die wenigen Frauen, die Mutigen.

Dies ist unter bestimmten Umständen nützlich, z. B. beim Ändern von Sonderzeichen am Zeilenanfang (z. B. beim Ersetzen der Größer-als-Symbole, die einige Leute verwenden, um vorheriges Material in E-Mail-Threads zu zitieren, durch einen horizontalen Tabulator, während eine algebraische Ungleichung in Anführungszeichen später in der Zeile unverändert bleibt), aber in Ihrem Beispiel, in dem Sie angeben, dass überall few wenn es ersetzt werden sollte, stellen Sie sicher, dass Sie das haben /g.

Die folgenden zwei Optionen (Flags) werden zu einer kombiniert, -ie:

-i option wird zum Bearbeiten verwendet in auf die Akte legen hello.txt.

-e option zeigt die expression / Befehl zum Ausführen, in diesem Fall s/.

Hinweis: Es ist wichtig, dass Sie verwenden -i -e suchen/ersetzen. Wenn du es tust -ie, erstellen Sie eine Sicherungskopie jeder Datei mit dem angehängten Buchstaben 'e'.

Das kannst du so machen:

locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g" 

Beispiele: um alle Vorkommen [logdir', "] (ohne [] ) durch [logdir', os zu ersetzen.getcwd()] Führen Sie in allen Dateien, die das Ergebnis des Befehls locate sind, Folgendes aus:

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"

wo [tensorboard/program.py ] ist eine zu durchsuchende Datei