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 | xargs
treten Probleme mit Leerzeichen, Anführungszeichen, Backslashes (und je nach Implementierung möglicherweise mehr xargs
) in Dateinamen auf.
Bei den GNU-Implementierungen von grep
und xargs
kö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
ripgrep
kann hier auch helfen. Ersetzen Sie foo durch das, was Sie suchen, und ändern Sie dann sowohl den rg
Aufruf als auch den sed
Ausdruck.
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