$ cat rgb
lower (#1): "red green blue"

$ sed '/#/ {s//=/; :k n; bk}' rgb
lower (=1): "red green blue"

I know that sed exits without autoprint if there is not any next line to append. However in this example sed printed the last line. How does it work?

     (next) If auto-print is not disabled, print the pattern space,
     then, regardless, replace the pattern space with the next line of
     input.  If there is no more input then 'sed' exits without
     processing any more commands.

The -n option disables autoprint.

You replaced # with = in the first line with # (the pattern space). The pattern space then got printed by n because there was no -n option. Then the pattern space was replaced with the next line, then we looped by to n, which caused the pattern space to be printed because autoprint was not disabled, and then there were no more lines of input so sed exited.

Maybe it's clearer if you use -n and add a p to your loop:

$ sed -n '/#/ {s//=/; :k n;p; bk}' rgb

after n, p forces printing of all but the first line.

$ sed -n '/#/ {s//=/; :k p;n; bk}' rgb
lower (=1): "red green blue"

before n, p forces the pattern space to be printed every time. n never prints anything, because autoprint is disabled.

Try removing the -n option with the p command in different positions in the loop.

If you only want to print one line after changing it, you could use q:

$ sed '/#/ s//=/;q' rgb
lower (=1): "red green blue"
| improve this answer | |
  • n command prints first, and then watch for the next input. Right? I thought sed always knows it is the last line, so it just exits without autoprint. Thanks Zanna, your answer is really helpful. – Smile Jan 11 '18 at 11:11
  • 1
    @Smile :) yes, n prints the pattern space first, then replaces it with the next line. The last line was read into the pattern space by n, then on the next loop it was printed, and there was nothing to replace it with so sed exited. You could say the n command quit halfway through its work, because it did the first step (print) then could not continue to the second step (replace) because there was no more input. – Zanna Jan 11 '18 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.