Newlines in BSD sed vs gsed

7

Das mit FreeBSD 11.2 p7 gelieferte sed bietet:

 $ seq 10 | sed 'N; l; D; p'
1$
2$
2$
3$
3$
4$
4$
5$
5$
6$
6$
7$
7$
8$
8$
9$
9$
10$

Während gsed (GNU sed 4.7) für dasselbe Skript gibt:

$ seq 10 | gsed 'N; l; D; p'
1\n2$
2\n3$
3\n4$
4\n5$
5\n6$
6\n7$
7\n8$
8\n9$
9\n10$
10

Wie können wir diesen Unterschied im Verhalten erklären?

Wolf-Revo-Katzen
quelle

Antworten:

8

BSD sedgibt bei lder Ausgabe von Zeichen in einer visuell eindeutigen Form keine Zeilenumbrüche in einer visuell eindeutigen Form aus.

Von sed (1) auf OpenBSD:

 [2addr]l
         (The letter ell.)  Write the pattern space to the standard output
         in a visually unambiguous form.  This form is as follows:

               backslash          \\
               alert              \a
               backspace          \b
               form-feed          \f
               carriage-return    \r
               tab                \t
               vertical tab       \v

(Beachten Sie die fehlende Erwähnung von Zeilenumbrüchen).

GNU sedenthält jedoch Zeilenumbrüche in den Zeichensatz, die eindeutig angezeigt werden sollen. Dies ist eine Erweiterung des Zeichensatzes, den der POSIX-Standard fürsed Erwähnungen verwendet (der Satz, den BSD sedverwendet). GNU sedverhält sich auch dann so, wenn --posixes in der Befehlszeile verwendet wird.

GNU sedgibt auch 10zweimal aus, BSD sednicht. Wenn Sie GNU sedmit POSIXLY_CORRECTset oder mit --posixausführen, wird es 10nur einmal ausgegeben , wie dies bei BSD der sedFall ist.

Dies liegt daran, dass GNU sedstandardmäßig den Teil der POSIX-Definition des sed NBefehls ignoriert, der besagt

Wenn keine nächste Eingabezeile verfügbar ist, Nverzweigt das Befehlsverb zum Ende des Skripts und wird beendet, ohne einen neuen Zyklus zu starten oder den Musterbereich in die Standardausgabe zu kopieren.

Beachten Sie auch, dass das pin Ihrem sedProgramm niemals ausgeführt wird, da Dein neuer Zyklus beginnt.

Kusalananda
quelle
2
Ein weiterer Unterschied besteht darin, dass 10 einmal mit BSD sed angezeigt wird, und diesmal verhält sich GNU sed wie BSD sed mit POSIXLY_CORRECT. Aus diesem Grund möchten Sie im Allgemeinen verwenden, $!Nanstatt Nwann -nnicht aktiviert ist.
Stéphane Chazelas
@ StéphaneChazelas Danke. Ich habe diesen Unterschied zuerst nicht bemerkt.
Kusalananda
Beachten Sie, dass sich das sed von ast-open wie \ndas von angezeigte GNU sed wrt verhält l. Ich vermute, dass die POSIX-Anforderung hier ein Versehen ist (sie sagen, dass sie nicht anwendbar ist, was hier keinen Sinn ergibt. Ich vermute, dass sie dies sagen, weil der Musterbereich normalerweise standardmäßig keine Zeilenumbrüche enthält, aber die Tatsache übersieht, dass sie von hinzugefügt werden können N, G, s ...; wenn sie das ursprüngliche sed-Verhalten fordern wollten, hätten sie gesagt, dass so etwas wie Newline buchstäblich ausgegeben werden soll oder so etwas)
Stéphane Chazelas