In der Linux-Shell sucht und ersetzt der folgende Befehl rekursiv alle Instanzen von 'this' durch 'that' (Ich habe keine Linux-Shell vor mir, aber das sollte reichen).
find . -name "*.txt" -print | xargs sed -i 's/this/that/g'
Wie sieht ein ähnlicher Befehl unter OSX aus?
OS X verwendet eine Mischung aus BSD- und GNU - Tools. Überprüfen Sie daher immer die Dokumentation (obwohl ich wusste, dass less
nicht einmal der OS X-Manpage entspricht):
https://developer.Apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/sed.1.html
sed nimmt das Argument nach -i
als Erweiterung für Backups. Geben Sie eine leere Zeichenfolge (-i ''
) für keine Sicherungen an.
Folgendes sollte tun:
find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +
Der -type f
ist nur eine gute Praxis. sed wird sich beschweren, wenn Sie ihm ein Verzeichnis geben oder so. .-exec
wird xargs
vorgezogen; Sie müssen sich nicht mit -print0
oder irgendetwas befassen. {} +
am Ende bedeutet, dass find
alle Ergebnisse als Argumente an eine Instanz des aufgerufenen Befehls anfügt, anstatt sie für jedes Ergebnis erneut auszuführen. (Eine Ausnahme ist, wenn die maximale Anzahl von Befehlszeilenargumenten, die das Betriebssystem zulässt, verletzt wird; in diesem Fall führt find
mehr als eine Instanz aus.)
Für den Mac wäre dies ein ähnlicher Ansatz:
find . -name '*.txt' -print0 | xargs -0 sed -i "" "s/form/forms/g"
Als alternative Lösung verwende ich diese unter Mac OSX 10.7.5
grep -ilr 'old-Word' * | xargs [email protected] sed -i '' 's/old-Word/new-Word/g' @
Credit geht an: Antwort von Todd Cesere
Unter Mac OSX 10.11.5 funktioniert das einwandfrei:
grep -rli 'old-Word' * | xargs [email protected] sed -i '' 's/old-Word/new-Word/g' @
Keine der oben genannten Funktionen funktionieren unter OSX.
Mach Folgendes:
Perl -pi -w -e 's/SEARCH_FOR/REPLACE_WITH/g;' *.txt
Eine Version, die sowohl unter Linux als auch unter Mac OS X funktioniert (durch Hinzufügen des Befehls -e
zu sed
):
export LC_CTYPE=C LANG=C
find . -name '*.txt' -print0 | xargs -0 sed -i -e 's/this/that/g'
Dies ist meine bearbeitbare. unter Mac OS X 10.10.4
grep -e 'this' -rl . | xargs sed -i '' 's/this/that/g'
Die oben genannten verwenden find ändern die Dateien, die den Suchtext nicht enthalten (fügen Sie am Ende der Datei eine neue Zeile hinzu), was ausführlich ist.
Wenn Sie ein zsh-Terminal verwenden, können Sie Platzhalter-Magie verwenden:
sed -i "" "s/search/high-replace/g" *.txt
find . -type f | xargs sed -i '' 's/string1/string2/g'
hier für weitere Informationen.
https://bitbucket.org/masonicboom/serp ist ein unter OSX getestetes go-Hilfsprogramm (dh plattformübergreifend), das rekursives Suchen und Ersetzen von Text in Dateien in einem bestimmten Verzeichnis durchführt und jeweils bestätigt Ersatz. Es ist neu und könnte fehlerhaft sein.
Verwendung sieht so aus:
$ ls test
a d d2 z
$ cat test/z
hi
$ ./serp --root test --search hi --replace bye --pattern "*"
test/z: replace hi with bye? (y/[n]) y
$ cat test/z
bye
Immer wenn ich diesen Befehl eingebe, scheine ich ihn immer zu verschließen oder eine Flagge zu vergessen. Ich habe ein Gist auf Github basierend auf TaylanUBs Antwort erstellt, das eine globale Suche aus dem aktuellen Verzeichnis ersetzt. Dies ist spezifisch für Mac OSX.
https://Gist.github.com/nateflink/9056302
Es ist schön, weil ich jetzt einfach ein Terminal aufklappen und dann kopieren:
curl -s https://Gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
Sie können einige seltsame Byte-Sequenzfehler erhalten. Hier ist der vollständige Code:
#!/bin/bash
#By Nate Flink
#Invoke on the terminal like this
#curl -s https://Gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: ./$0 [find string] [replace string]"
exit 1
fi
FIND=$1
REPLACE=$2
#needed for byte sequence error in ascii to utf conversion on OSX
export LC_CTYPE=C;
export LANG=C;
#sed -i "" is needed by the osx version of sed (instead of sed -i)
find . -type f -exec sed -i "" "s|${FIND}|${REPLACE}|g" {} +
exit 0
Ich habe dieses Format verwendet - aber ... Ich musste es drei oder mehr Mal ausführen, damit es wirklich jede Instanz ändert, die ich sehr seltsam fand. Wenn Sie es einmal ausführen, würde sich in jeder Datei etwas ändern, aber nicht in allen. Wenn Sie die gleiche Zeichenfolge zwei bis vier Mal ausführen, werden alle Instanzen erfasst.
find . -type f -name '*.txt' -exec sed -i '' s/thistext/newtext/ {} +