Ich habe erfolgreich den folgenden sed
-Befehl zum Suchen/Ersetzen von Text in Linux verwendet:
sed -i 's/old_link/new_link/g' *
Wenn ich es jedoch auf meinem Mac OS X versuche, bekomme ich:
"Befehl c erwartet\gefolgt von Text"
Ich dachte, mein Mac hat eine normale BASH-Shell. Wie geht's?
BEARBEITEN:
Laut @High Performance liegt dies daran, dass Mac sed
eine andere (BSD-) Variante hat. Meine Frage wäre also, wie repliziere ich diesen Befehl in BSD sed
?
BEARBEITEN:
Hier ist ein aktuelles Beispiel, das dies verursacht:
sed -i 's/hello/gbye/g' *
Wenn Sie die Option -i verwenden, müssen Sie eine Erweiterung für Ihre Sicherungen angeben.
Wenn Sie haben:
File1.txt
File2.cfg
Der Befehl (beachten Sie den Mangel an Platz zwischen -i
und ''
und -e
, damit er auf neuen Versionen von Mac und auf GNU funktioniert):
sed -i'.original' -e 's/old_link/new_link/g' *
erstellen Sie 2 Sicherungsdateien wie:
File1.txt.original
File2.cfg.original
Es gibt keinen tragbaren Weg, um die Erstellung von Sicherungsdateien zu vermeiden, da es unmöglich ist, eine Kombination aus sed-Befehlen zu finden, die in allen Fällen funktioniert:
sed -i -e ...
- funktioniert nicht unter OS X, da -e
-Sicherungen erstellt werdensed -i'' -e ...
- funktioniert nicht unter OS X 10.6, funktioniert jedoch unter 10.9+sed -i '' -e ...
- funktioniert nicht mit GNUHinweis Da es keinen sed-Befehl gibt, der auf allen Plattformen funktioniert, können Sie versuchen, einen anderen Befehl zu verwenden, um dasselbe Ergebnis zu erzielen
z.B. Perl -i -pe's/old_link/new_link/g' *
Ich glaube unter OS X, wenn Sie -i verwenden, ist eine Erweiterung für die Sicherungsdateien erforderlich . Versuchen:
sed -i .bak 's/hello/gbye/g' *
Mit GNU sed
ist die Erweiterung optional .
Dies funktioniert sowohl mit GNU als auch mit BSD-Versionen von sed:
sed -i'' -e 's/old_link/new_link/g' *
oder mit backup:
sed -i'.bak' -e 's/old_link/new_link/g' *
Fehlendes Leerzeichen nach -i
-Option beachten! (Notwendig für GNU sed)
Hatte das gleiche Problem in Mac und löste es mit brew
:
brew install gnu-sed
und verwenden als
gsed SED_COMMAND
sie können sed
als Alias auch auf gsed
setzen (wenn Sie möchten):
alias sed=gsed
Sie können auch die GNU - Version von sed (gsed) in Ihrem Mac installieren und mit der Linux-Standardsyntax verwenden.
Installieren Sie dazu gsed
mit Ports (wenn Sie nicht über diese verfügen, erhalten Sie sie unter http://www.macports.org/ ), indem Sie Sudo port install gsed
ausführen. Dann können Sie sed -i 's/old_link/new_link/g' *
ausführen.
Die Antwort von Sinetris ist richtig, aber ich verwende dies mit dem Befehl find
, um genauer zu sagen, welche Dateien ich ändern möchte. Im Allgemeinen sollte dies funktionieren (getestet mit osx /bin/bash
):
find . -name "*.smth" -exec sed -i '' 's/text1/text2/g' {} \;
Im Allgemeinen ist die Verwendung von sed
ohne find
in komplexen Projekten weniger effizient.
Ihr Mac hat zwar eine BASH-Shell, aber es ist eher eine Frage, mit welcher Implementierung von sed Sie sich befassen. Auf einem Mac kommt Sed aus BSD und unterscheidet sich geringfügig von dem, den Sie in einer typischen Linux-Box finden. Ich schlage vor, Sie man sed
.
So können Sie Umgebungsvariablen auf die Vorlagendatei anwenden (kein Backup erforderlich).
echo "Hello {{FOO}}" > foo.conf.tmpl
FOO="world" && sed -e "s/{{FOO}}/$FOO/g" foo.conf.tmpl > foo.conf
Beide arbeiten - macOS 10.12.4 und Ubuntu 14.04.5
sed -ie 's/old_link/new_link/g' *
Funktioniert sowohl unter BSD als auch unter Linux
Wie die anderen Antworten zeigen, gibt es keine Möglichkeit, Sed port portabel unter OS X und Linux zu verwenden, ohne Sicherungsdateien zu erstellen. Also habe ich stattdessen diesen Ruby One-Liner dazu benutzt:
Ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml
In meinem Fall musste ich es von einer rake
-Task aus aufrufen (d. H. Innerhalb eines Ruby-Skripts). Daher habe ich diese zusätzliche Zitierstufe verwendet:
sh %q{Ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml}
Ich habe eine Funktion erstellt, um sed
Unterschied zwischen MacOS (getestet unter MacOS 10.12) und anderen Betriebssystemen zu behandeln:
OS=`uname`
# $(replace_in_file pattern file)
function replace_in_file() {
if [ "$OS" = 'Darwin' ]; then
# for MacOS
sed -i '' -e "$1" "$2"
else
# for Linux and Windows
sed -i'' -e "$1" "$2"
fi
}
Verwendungszweck:
$(replace_in_file 's,MASTER_Host.*,MASTER_Host='"$MASTER_IP"',' "./mysql/.env")
Woher:
,
ist ein Delimeter
's,MASTER_Host.*,MASTER_Host='"$MASTER_IP"','
ist Muster
"./mysql/.env"
ist der Pfad zur Datei