Wie finde und ersetze ich jedes Vorkommen von:
subdomainA.example.com
mit
subdomainB.example.com
in jeder Textdatei unter dem /home/www/
Verzeichnisbaum rekursiv?
Wie finde und ersetze ich jedes Vorkommen von:
subdomainA.example.com
mit
subdomainB.example.com
in jeder Textdatei unter dem /home/www/
Verzeichnisbaum rekursiv?
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
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
.
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 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.
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.
4 Stimmen
Kleiner Tipp für alle, die sed verwenden: Es fügt Zeilenumbrüche an Ihre Dateien an. Wenn Sie das nicht wollen, machen Sie zuerst ein find-replace, das mit nichts übereinstimmt, und übergeben Sie das an Git. Dann führen Sie die echte Ersetzung durch. Dann rebase interaktiv und lösche das erste.
0 Stimmen
@funroll Oder verwenden Sie ein Werkzeug, das das Hinzufügen von Zeilenumbrüchen nicht erzwingt, wie z.B. Perl, oder akzeptieren Sie die Tatsache, dass POSIX strikt vorschreibt, dass Textdateien Zeilenabschlüsse haben müssen.
6 Stimmen
Sie können ein Verzeichnis, wie z. B. git, von den Ergebnissen ausschließen, indem Sie
-path ./.git -prune -o
においてfind . -path ./.git -prune -o -type f -name '*matchThisText*' -print0
vor der Übergabe an xargs0 Stimmen
Diese Antwort auf der Unix-Website StackExchange ist ebenfalls sehr interessant: unix.stackexchange.com/a/112024/354626
0 Stimmen
Alternative Lösung von SuperUser Wie kann ich eine rekursive Suche und Ersetzung über die Befehlszeile durchführen? :
find . -type f \( -iname \*.ht* -o -iname \*.php \) -exec sed -i'' -e 's/findString/replString/g' {} +
(Zeichenketten müssen escaped werden, z.B. Punkte wie\.
) Ignoriert möglicherweise Dateinamen mit Leerzeichen(?)