Subject: Re: bug#22427: Odd behaviour of sed with n/N and line ranges

From: Jim Meyering <[email-masked]>
Date: Sat, 6 Feb 2016 22:22:51 -0800

On Fri, Jan 22, 2016 at 4:45 AM, Jim Meyering <[email-masked]> wrote:
> On Fri, Jan 22, 2016 at 4:02 AM, Eric Blake <[email-masked]> wrote:
>> This message came up on the POSIX list today, claiming GNU sed has a bug:
>>
>> On 01/21/2016 12:02 PM, Rob Landley wrote:
>>> On Thu, Jan 21, 2016 at 4:38 AM, Geoff Clare <[email-masked]> wrote:
>>>> I'm seeing this with versions of sed derived from System V:
>>>>
>>>> $ printf '%s\n' a b | sed -e n -e '2s/b/c/'
>>>> a
>>>> c
>>>> $ printf '%s\n' a b | sed -e n -e '1,2s/b/c/'
>>>> a
>>>> b
>>>
>>> Having recently implemented toybox sed from the posix spec, that's
>>> what my implementation is producing too.
>>>
>>> You have to match the first line of a range in order to activate the
>>> range (numeric works same as /ascii/ that way). Since the above skips
>>> past the first line, you never activate the range, so later lines
>>> don't trigger the range contents either,
>>>
>>> The gnu behavior is wrong. Replace the 1 with /a/ and the logic may be
>>> easier to follow
>>>
>>> (But hey, at least the gnu guys finally fixed "sed p - -" segfaulting
>>> when it freed stdin the second time...)
>
> Thanks to both of you.
> I'll certainly take a look before the upcoming release.

I'm not convinced that this should be changed.
First, the vendor sed from Solaris 5.10 works the same way
GNU sed does, and so does the one from busybox-1.22.1.

Second, and perhaps more importantly, it feels like
claiming the 1,2 range fails to match line 2 because
the beginning address, "1", never matched a line
(that was skipped due to the "n") is failing on a
technicality. I think of the M,N (M<N) line number
address range as matching any line in [M..N],
regardless of whether line M happens to be processed.

I feel that an address spec like 1,9 is conceptually
different from one that specifies /a/,9. The latter
specifies a dynamic condition: testing whether /a/
matches each pattern space, while the former
specifies a static condition: a range of line numbers,
that is independent of whether line "1" never sees the
substitution command, due to thae initial "n" command.