Zeichenfolgen in Dateien rekursiv ersetzen

Zeichenfolgen in Dateien rekursiv ersetzen

Ich möchte den Backslash in der Zeichenfolge durch einen Schrägstrich ersetzen page_path\example_filename.txt. Außerdem möchte ich dies auf einem großen Dateisystem ausführen und alle Verzeichnisse rekursiv durchsuchen können.

Ich habe im Internet jemanden gefunden, der mir sagte, ich solle grep, xargs, und verwenden sed, aber ich habe es nicht zum Laufen gebracht. Ich habe verschiedene Variationen von Trennzeichen und Escape-Zeichen ausprobiert, aber es hat nicht geklappt.

Hier ist der Befehl, den ich ausführen wollte:
grep -lr -e 'page_path\\' * | xargs sed -i 's/page_path\/page_path//g'

Dank im Voraus.

Antwort1

Mit grep | xargstreten Probleme mit Leerzeichen, Anführungszeichen, Backslashes (und je nach Implementierung möglicherweise mehr xargs) in Dateinamen auf.

Bei den GNU-Implementierungen von grepund xargskönnen Sie diese Probleme vermeiden, indem Sie Folgendes verwenden: grep -lZr ... | xargs -r0 sed ...Dabei werden Null-Bytes als Trennzeichen verwendet.

s/a/b/Und nun zum sed-Befehl: Der Trick besteht darin, dass man als Trennzeichen statt dessen jedes andere Zeichen verwenden kann , zB s#a#b#:

sed -i 's#page_path\\#page_path/#g'

Antwort2

Sie können hierfür auch find verwenden:

find /your/path -type f -exec grep -l 'page_path\\' {} \; -exec sed -i 's#page_path\\#page_path/#g' {} \;

Die zweite Ausführung wird nur durchgeführt, wenn die erste erfolgreich war, und Sie bekommen keine Probleme mit nicht druckbaren oder Escape-Zeichen benötigenden Zeichen in Dateinamen.

Antwort3

Warum CPU-Zyklen für das Aufrufen all dieser Befehle verschwenden, wennSchlaghat eine Funktion integriert, die es mit VIEL weniger Tipparbeit ermöglicht?

Beispiel

str='page_path\example_filename.txt'
echo "${str//\\/\/}"

Ausgabe

page_path/example_filename.txt

Antwort4

ripgrepkann hier auch helfen. Ersetzen Sie foo durch das, was Sie suchen, und ändern Sie dann sowohl den rgAufruf als auch den sedAusdruck.

rg foo --files-with-matches | xargs sed -i 's/foo/bar/g'

Wenn Ihre Dateien Leerzeichen in ihren Namen enthalten, weisen Sie ripgrep an, sie durch NULL-Bytes zu trennen.

rg foo --files-with-matches -0 | xargs -0 sed -i 's/foo/bar/g'

Quelle:https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md#search-and-replace

verwandte Informationen