904 Stimmen

Wie kann ich ein rekursives Suchen/Ersetzen einer Zeichenkette mit awk oder sed durchführen?

Wie finde und ersetze ich jedes Vorkommen von:

subdomainA.example.com

mit

subdomainB.example.com

in jeder Textdatei unter dem /home/www/ Verzeichnisbaum rekursiv?

114 Stimmen

Tipp: Führen Sie die folgenden Schritte nicht in einem svn-Checkout-Baum durch... es wird die magischen .svn-Ordnerdateien überschreiben.

9 Stimmen

Oh mein Gott, das ist genau das, was ich gerade getan habe. Aber es hat funktioniert und es scheint keinen Schaden angerichtet zu haben. Was könnte schlimmstenfalls passieren?

5 Stimmen

@J.Katzwinkel: Zumindest können die Prüfsummen beschädigt werden, was wiederum Ihr Repository beschädigen kann.

18voto

Sazzad Hissain Khan Punkte 33230

Der einfachste Weg zu ersetzen ( alle Dateien, Verzeichnis, rekursiv )

find . -type f -not -path '*/\.*' -exec sed -i 's/foo/bar/g' {} +

Anmerkung: Manchmal müssen Sie vielleicht einige versteckte Dateien ignorieren, z. B. .git können Sie den obigen Befehl verwenden.

Wenn Sie versteckte Dateien einbeziehen wollen, verwenden Sie,

find . -type f  -exec sed -i 's/foo/bar/g' {} +

In beiden Fällen wird die Zeichenfolge foo wird durch eine neue Zeichenkette ersetzt bar

18voto

Jimmy Kane Punkte 15004

Ein schöner Oneliner als Extra. Mit git grep.

git grep -lz 'subdomainA.example.com' | xargs -0 perl -i'' -pE "s/subdomainA.example.com/subdomainB.example.com/g"

14voto

unutbu Punkte 769083
find /home/www/ -type f -exec perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

find /home/www/ -type f listet alle Dateien in /home/www/ (und seinen Unterverzeichnissen) auf. Mit dem Flag "-exec" wird find angewiesen, für jede gefundene Datei den folgenden Befehl auszuführen.

perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

ist der Befehl, der für die Dateien ausgeführt wird (viele auf einmal). Der {} wird durch Dateinamen ersetzt. Die + am Ende des Befehls sagt find um einen Befehl für viele Dateinamen zu erstellen.

Gemäß der find man-Seite: "Die Kommandozeile wird auf die gleiche Weise aufgebaut, wie xargs seine Befehlszeilen aufbaut."

Es ist also möglich, Ihr Ziel zu erreichen (und Dateinamen mit Leerzeichen zu behandeln), ohne dass Sie xargs -0 , oder -print0 .

9voto

microo8 Punkte 3284

Oder verwenden Sie das rasend schnelle GNU Parallel:

grep -rl oldtext . | parallel sed -i 's/oldtext/newtext/g' {}

9voto

Henno Punkte 1360

Ich brauchte dies einfach und war mit der Geschwindigkeit der verfügbaren Beispiele nicht zufrieden. Also habe ich mir etwas Eigenes ausgedacht:

cd /var/www && ack-grep -l --print0 subdomainA.example.com | xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'

Ack-grep ist sehr effizient beim Auffinden relevanter Dateien. Dieser Befehl ersetzte ~145 000 Dateien im Handumdrehen, während andere so lange brauchten, dass ich nicht warten konnte, bis sie fertig waren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X