Wie suche und ersetze ich mehrere Nadeln durch ein Wort über einen Ausdruck?


8

Angenommen, Sie haben eine Textdatei:

foo fnord bar
bizz foo poit

Und jetzt möchte ich sowohl "foo" als auch "bar" durch "narf" ersetzen.

Ich weiß, ich könnte gebrauchen:

 sed -e 's/foo/narf/g' -e 's/bar/narf/g' fileName

Ich möchte jedoch mit einem ODER-Operator arbeiten, der dem regulären Ausdruck sagt, dass beide Nadeln über einen Ausdruck übereinstimmen sollen.

Ich denke, das Rohr sollte meinen Bedürfnissen entsprechen, aber ich habe es versucht

sed -e 's/foo|bar/narf/g' -i fileName

und es hat nicht funktioniert und es wirft nicht einmal einen Fehler.

Was mache ich hier falsch?

Antworten:


10

Verwenden Sie die -rOption für die erweiterte Regexp-Syntax:

sed -r -e 's/foo|bar/narf/g'

Ansonsten entkomme der Disjunktion als \|:

sed -e 's/foo\|bar/narf/g'

6

Es gibt viele Variationen der Syntax regulärer Ausdrücke . Die allerersten Tools in der Unix-Welt, die reguläre Ausdrücke hatten, verfügten nicht über die vollen Funktionen regulärer Ausdrücke, sondern nur über Zeichensätze ( […]und .), Wiederholungen ( *) und Linienanker ( ^und $). Grundlegende reguläre Ausdrücke haben nur diese Operatoren. Sed ist ein Werkzeug der alten Schule und verwendet grundlegende reguläre Ausdrücke.

Viele sed-Implementierungen verfügen über Erweiterungen für den vollständigen regulären Ausdruck. Da der Charakter |für sich selbst steht, müssen Sie ihn \|zur Abwechslung und ähnlich \(und \)zur Gruppierung verwenden. Beachten Sie, dass der POSIX-Standard nicht vorschreibt, \|dass er in regulären Grundausdrücken unterstützt wird , und dass einige Systeme (z. B. OpenBSD ) ihn nicht haben.

Einige Versionen von sed haben eine Option wechseln erweiterte reguläre Ausdrücke , in denen (…)für die Gruppierung und verwendet wird |für Abwechslung. Übergeben Sie die -rOption mit GNU sed (dh unter Linux oder Cygwin) oder Busybox . Übergeben Sie unter FreeBSD oder OSX die -EOption.

Wenn Ihr Sed keinen Wechsel hat, können Sie awkstattdessen anrufen . Es wird von POSIX vorgeschrieben , ist jedoch für diese Aufgabe etwas ausführlich und unterstützt keine Rückreferenzen.

awk '{gsub(/foo|bar/, "narf")}' <fileName.old >fileName.new

Übrigens unterstützen nur GNU und Busybox sed das Ersetzen von Dateien. Awk und andere Versionen von sed tun dies nicht. Siehe Kann ich eine Datei an einer Stelle ändern?

Wenn Sie über Perl verfügen, ist dies für die Textverarbeitung von Einzeilern häufig praktisch. Das meiste, was in sed, awk und dem Rest einfach ist, ist in Perl nicht viel schwieriger, und Sie können ein einziges (wenn auch komplexes) Werkzeug erlernen.

perl -i -pe 's/foo|bar/narf/g' fileName

0

Sie können Vim im Ex-Modus verwenden:

ex -sc '%s/\vPA|QU/RO/g|x' file
  1. % Wählen Sie alle Zeilen aus

  2. s Ersatz

  3. \v Magie einschalten

  4. g global ersetzen

  5. x speichern und schließen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.