Verwendung der Abwechslung "|" in sed's Regex

79

Ich benutze sed, GNU sed Version 4.2.1. Ich möchte die Abwechslung "|" Symbol in einem Unterausdruck. Beispielsweise :

echo "blia blib bou blf" | sed 's/bl\(ia|f\)//g'

sollte zurückkehren

" blib bou "

aber es kehrt zurück

"blia blib bou blf".

Wie kann ich das erwartete Ergebnis erzielen?

Cedric
quelle

Antworten:

110

Das "|" braucht auch einen Backslash, um seine besondere Bedeutung zu bekommen.

echo "blia blib bou blf" | sed 's/bl\(ia\|f\)//g'

werde tun was du willst.

Wie Sie wissen, lesen Sie das Handbuch, wenn alles andere fehlschlägt :-).

GNU sed Benutzerhandbuch , Abschnitt 3.3 Übersicht über die Syntax regulärer Ausdrücke :

`REGEXP1 \ | REGEXP2 '

Entspricht entweder REGEXP1 oder REGEXP2.

Beachten Sie den Backslash ...

Leider ist die Regex-Syntax nicht wirklich standardisiert ... es gibt viele Varianten, die sich unter anderem darin unterscheiden, welche "Sonderzeichen" \ benötigen und welche nicht. In einigen Fällen ist es sogar konfigurierbar oder hängt von Schaltern ab (wie in GNU grep, wo Sie zwischen drei verschiedenen Regex-Dialekten wechseln können).

Diese Antwort ist insbesondere für GNU sed . Es gibt andere sedVarianten, zum Beispiel die in den BSDs verwendeten, die sich unterschiedlich verhalten.

sleske
quelle
35
Für alle anderen, die durch diese Antwort verwirrt sind \ | funktioniert nur in gnu sed (gsed auf os x) nicht vanilla sed (sed auf os x).
Andrew Hancox
@ AndrewHancox Vielen Dank! Ich wollte mir gerade die Haare aus dem Kopf reißen (und bis jetzt geht es mir ziemlich gut im Vergleich zu meinem Manager an der Haarfront). Ich weiß, dass ich RegEx genug kenne, um es zu versuchen und \ | Aber ich habe nie darüber nachgedacht, dass OSX tatsächlich ein Non-Gnu-Sed verwenden könnte.
Phatskat
8
Die Standardversion von BSD / OS X sedunterstützt die Abwechslung, jedoch nur mit "erweiterter" Regex-Syntax ( -E) - was bedeutet, dass weder die Pipes noch die Klammern echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
Mark Reed
2
Ich habe meine Antwort bearbeitet, um festzustellen, dass sie nur für GNU sed ist.
Sleske
23

Da es einige Kommentare zu Nicht-Gnu- sedImplementierungen gibt: Zumindest unter OS X können Sie das -EArgument verwenden, um  sed:

Interpretieren Sie reguläre Ausdrücke als erweiterte (moderne) reguläre Ausdrücke und nicht als einfache reguläre Ausdrücke (Basic Regular Expressions, BREs). Die Manualpage re_format (7) beschreibt beide Formate vollständig.

Dann können Sie Metazeichen mit regulären Ausdrücken verwenden, ohne sie zu maskieren. Beispiel:

$ echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
 blib bou 
Daniel Beck
quelle
12

GNU sed unterstützt auch die -rOption (erweiterte reguläre Ausdrücke). Dies bedeutet, dass Sie den Metazeichen nicht entkommen müssen:

echo foohello barhello | sed -re "s/(foo|bar)hello/hi/g"

Ausgabe:

hi hi
jco
quelle
Ja, die -rOption ist wirklich sehr hilfreich für die Lesbarkeit der Ausdrücke. Das sollte die akzeptierte Antwort sein.
рüффп
9

Das \|funktioniert auch nicht mit sed unter Solaris 10. Was ich tat, war Gebrauch

perl -p -e 's/bl(ia|f)//g'
Joe Tennies
quelle
2
+1 für Portabilität, da ein System, wenn es über Perl verfügt, im Gegensatz zu sed immer diese Syntax verwendet.
Übelsuppe
4

Followup: sed -E erlaubt es unter MacOS. Kein Backslash nötig für |.

 sed -E 's/this|orthat/oooo/g' infile
einige Ideen
quelle
1

In der GnuWin32 unter Windows sed ist die Syntax sed "s/thing1\|thing2/ /g" source > destination.

Die Anführungszeichen müssen vom Typ ""Erforderlich" sein, damit der Befehl analysiert werden kann.

Twobob
quelle