Subject: bug#19842: sed bug: using -e instead of a literal newline in s replacement fails

From: Assaf Gordon <[email-masked]>
Date: Tue, 24 Jan 2017 23:05:58 -0500

tag 19842 notabug
close 19842
stop

Hello Evan and all,

I'm triaging old sed bugs.
(for past discussion, see https://bugs.gnu.org/19842 ).

First,
for completeness, this is the behavior with various sed implementations:

$ echo foo | sed-gnu-4.3 -e 's/foo/bar\' -e 'baz/'
sed: -e expression #1, char 10: unterminated `s' command

$ echo foo | sed-netbsd-7.0 -e 's/foo/bar\' -e 'baz/'
bar
baz

$ echo foo | sed-freebsd-10 -e 's/foo/bar\' -e 'baz/'
bar
baz

$ echo foo | sed-openbsd-5.9 -e 's/foo/bar\' -e 'baz/'
barbaz

$ echo foo | sed-heirloom -e 's/foo/bar\' -e 'baz/'
Undefined label: az/

$ echo foo | sed-busybox -e 's/foo/bar\' -e 'baz/'
bar
baz

Second,
Notice the backslash plays a role, indicating continuation for some
implementations. Without backslash, '-e' are not always concatenated:

$ echo foo | sed-netbsd-7.0 -e 's/foo/bar' -e 'baz/'
sed-netbsd-7.0: 1: "s/foo/bar
": unescaped newline inside substitute pattern

$ echo foo | sed-freebsd-10 -e 's/foo/bar' -e 'baz/'
sed-freebsd-10: 1: "s/foo/bar
": unescaped newline inside substitute pattern

$ echo foo | sed-openbsd-5.9 -e 's/foo/bar' -e 'baz/'
barbaz

$ echo foo | sed-busybox -e 's/foo/bar' -e 'baz/'
sed: unmatched '/'

Third,
even in OpenBSD's sed which accepts this construct,
it seems this is limited to 's'. It doesn't "just work"
in all commands:

$ echo a | sed-openbsd-5.9 -e 'y/abc/123/'
1

$ echo a | sed-openbsd-5.9 -e 'y/abc/1\' -e '23/'
sed: 1: "y/abc/1\": unterminated transform target string

$ echo a | sed-openbsd-5.9 -e 'y/abc/1' -e '23/'
sed: 1: "y/abc/1": unterminated transform target string

as opposed to Busybox where it does work:

$ echo a | sed-busybox -e 'y/abc\' -e '/123/'
1

Lastly,
GNU sed does have one special case where trailing backslash
plays a role: in a/c/i commands. This is specifically done
to facilitate programs such as:

$ echo a | sed-gnu-4.3 -e '1i\' -e 'foobar'
foobar
a

$ echo a | sed-openbsd-5.9 -e '1i\' -e 'foobar'
foobara

$ echo a | sed-netbsd-7.0 -e '1i\' -e 'foobar'
sed-netbsd-7.0: 1: "foobar
": invalid command code f

As such,
I would say that this is not bug per-se in gnu sed.
It is not clear what is the correct behavior, and depending
on one's POSIX interpretation might even be undefined.

I'm marking this as 'done', but discussion can continue by replying to
this thread. Better yet - if you have a patch that adds this
functionality without causing regressions, we can look into
incorporating it.

regards,
- assaf