[Bug 271817] sed: range change with N results in no output

From: <bugzilla-noreply_at_freebsd.org>
Date: Sun, 18 Jun 2023 22:59:22 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=271817

--- Comment #5 from Andrew "RhodiumToad" Gierth <andrew@tao11.riddles.org.uk> ---
(In reply to Mohamed Akram from comment #4)

This is the sequence of events according to the spec, as I read it:

1. Read line "a" into the pattern space.
2. Execute the first command:
    /a/ matches, so we begin an addressed range
    "c" deletes the pattern space (but does not emit anything and does not
start the next cycle)
3. Execute the second command:
    $ does not match
    ! inverts the match
    N is executed, which appends "\nb" to the (deleted) pattern space
4. By my reading of the spec, the "\nb" should be output at this point. For
whatever reason, BSD sed does not do that.
5. The pattern space is deleted (as this is the end of the cycle)
6. Read line "c" into the pattern space.
7. Execute the first command:
    /b/ does not match, so we are still in an addressed range
    "c" deletes the pattern space (but does not emit anything and does not
start the next cycle)
8. Execute the second command:
    $ does not match
    ! inverts the match
    N is executed, which appends "\nd" to the (deleted) pattern space
9. as 4.
10. The pattern space is deleted (as this is the end of the cycle)
11. read line "e" into the pattern space.
12. Execute the first command:
    /b/ does not match, so we are still in an addressed range
    "c" deletes the pattern space (but does not emit anything and does not
start the next cycle)
13. Execute the second command:
    $ does not match
    ! inverts the match
    N is executed, which appends "\nf" to the (deleted) pattern space
14. as 4.
15. The pattern space is deleted (as this is the end of the cycle).
16. There are no more lines so the process ends. Note that neither the last
line of input, nor any line containing /b/, was never processed by the "c"
command, so it never has a chance to emit the replacement text.

You seem to be hung up on /a/,/b/ representing some block of input lines. This
is NOT WHAT IT MEANS; it means "start a range when you see a _pattern space_
matching /a/, and end it when you see a pattern space matching /b/". By using N
to process some input lines, you prevent them from being seen in the pattern
space at the start of the script, which affects how the first command
determines its range.

Alternatively, you (or GNU sed) may be assuming that "c" starts a new cycle
(rather than executing the rest of the script) for every row of a 2-address
range, not just the last one. This isn't what the spec actually says (as you
quoted yourself), though it might be considered to be more useful or
consistent. (I looked for applicable defect reports against the spec, didn't
find any.)

-- 
You are receiving this mail because:
You are the assignee for the bug.