it-swarm.com.de

Rekursives Suchen und Ersetzen in Textdateien unter Mac und Linux

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?

97
Jack

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.)

206
TaylanUB

Für den Mac wäre dies ein ähnlicher Ansatz:

find . -name '*.txt' -print0 | xargs -0 sed -i "" "s/form/forms/g"
109
Will

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

11
Maciej Gurban

Unter Mac OSX 10.11.5 funktioniert das einwandfrei:

grep -rli 'old-Word' * | xargs [email protected] sed -i '' 's/old-Word/new-Word/g' @
10
madx

Keine der oben genannten Funktionen funktionieren unter OSX.

Mach Folgendes:

Perl -pi -w -e 's/SEARCH_FOR/REPLACE_WITH/g;' *.txt
7
eb80

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'
7
vroc

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.

1
NoteCode

Wenn Sie ein zsh-Terminal verwenden, können Sie Platzhalter-Magie verwenden:

sed -i "" "s/search/high-replace/g" *.txt

1
Mentor
find . -type f | xargs sed -i '' 's/string1/string2/g'

hier für weitere Informationen.

0
user2725109

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
0
user4425237

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
0
Nate Flink

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/ {} +
0
user1399145