In der POSIX- sed
Spezifikationdiese Aussageist zu finden (meine Hervorhebung):
Die Escape-Sequenz „\n“ muss mit einem im Musterbereich eingebetteten <newline> übereinstimmen.Ein wörtliches <newline> darf nicht verwendet werdenim BRE einer Kontextadresse oderin der Ersatzfunktion.
Der folgende GNU- sed
Befehl mit --posix
Flag widerspricht dieser Spezifikation, da in der Ersetzungsfunktion eine neue Zeile verwendet wird.
$ printf '1X2' | sed --posix 's|X|\n|'
1
2
Warum wurde also sed
eine neue Zeile eingefügt, anstatt eine Fehlermeldung auszugeben?
Antwort1
„Ein wörtliches <newline> darf nicht verwendet werden“, In Ihrem Beispiel wird kein wörtliches Newline verwendet. Daher ist dieser Teil des Standards nicht relevant.
\n
Istnichtein wörtlicher Zeilenumbruch.
Antwort2
Das --posix
Flag macht GNU sed
POSIX-kompatibel.
POSIX lässt das Verhalten s/x/\n/
unspezifiziert:
Die Bedeutung eines nicht maskierten <Backslash>, auf den unmittelbar ein anderes Zeichen als „&“, <Backslash>, eine Ziffer, <Newline> oder das für diesen Befehl verwendete Trennzeichen folgt, ist nicht festgelegt.
Das Ersetzen x
durch n
, durch \n
, durch Newline, das Melden eines Fehlers und das Neustarten Ihres Computers sind also alles konforme Verhaltensweisen. Es gibt keinen Grund, warum GNU sed
sein Verhalten hier ändern sollte.
Eine konformeAnwendung(also in diesem Fall Skript) dürfen \n
dort nicht verwendet werden, darum geht es in dem von Ihnen zitierten Text.
Anders verhält es sich dort, wo POSIX verlangt, sowohl als auch durch s/[\t]/x/g
zu ersetzen . Dort werden Sie sehen, dass sich das Verhalten von GNU mit ändert . Für ist die POSIX-Spezifikation tatsächlich mehrdeutig. GNU ändert sein Verhalten mit , sodass es und durch ersetzt , aber es ist nicht so klar, ob das nötig ist oder nicht.\
t
x
sed
--posix
s/[\n]/x/g
sed
--posix
\
n
x
Antwort3
Der Standard legt fest, dass in derSuchmuster(BRE, Basic Regular Expression, in POSIX-Sprache) kein expliziter Zeilenumbruch verwendet werden kann und dass ein Zeilenumbruch durch '\n' dargestellt wird; und er kann nicht verwendet werden inErsatzentweder.
Ihr Suchmuster enthält keine Zeilenumbrüche, weder explizit noch durch '\n' dargestellt. Sie haben ein '\n' im Ersetzungstext. Oben steht nicht, wie ein Zeilenumbruch im Ersetzungstext dargestellt werden soll (falls überhaupt). GNU sed interpretiert das Vorherige so, dass das Ersetzen durch '\n' die Einführung eines Zeilenumbruchs bedeutet. Sinnvoll.