3

I noticed the following interesting behavior:

$ printf '%s\n' line{1..2} | sed $'1a\\\nPREFIX'
line1
PREFIXline2
$ 

Interestingly, this behavior is only possible for the last command in a Sed script, as to put another command afterwards requires a newline.

It also works with the insert command:

$ printf '%s\n' line{1..2} | sed $'1i\\\nPREFIX'
PREFIXline1
line2
$ 

Can this behavior be depended upon?

I don't see it mentioned one way or another in the POSIX specs for Sed. It just says that the text may consist of one or more lines. (If a line doesn't end in a newline character, is it still a line?)

It also works with multiple line insertions:

$ printf '%s\n' line{1..2} | sed $'1a\\\n ****/\n1i\\\n/****\\\n * '
/****
* line1
****/
line2
$ 
  • 1
    Related; my earlier misadventures with BSD Sed: unix.stackexchange.com/q/312579/135943 – Wildcard Sep 7 '17 at 3:42
  • I consider this behaviour to be inconsistent, as the newline following the insertion is not part of the insertion, but closes the a/i command, so it should not be treated different from the insertion at the end of the script. Whether or not the newline is to be output at all, is ambiguous in the standard, as I see it, so theoretically your sed could insert it or not, but should to it independent from whether this is the last command. – Philippos Sep 7 '17 at 6:21
  • 2
    That's clearly a bug. POSIX does say for that script given as argument: A string to be used as the script of editing commands. The application shall not present a script that violates the restrictions of a text file except that the final character need not be a newline implying that the newline is implied. sed -e x is the same as sed -f file where file contains x\n. Actually, you'll find that sed -e script works OK, only sed script has the issue confirming even more clearly that it is a bug. – Stéphane Chazelas Sep 7 '17 at 6:36
0

I just tested with a different Sed and found this is a peculiarity of BSD Sed; GNU Sed gives different results best illustrated with the output of the last command given above:

$ printf '%s\n' line{1..2} | sed $'1a\\\n ****/\n1i\\\n/****\\\n * '
/****
 *
line1
 ****/
line2
$
0

To prefix a line with a string, use a substitution (s) and replace ^, the start-of-line anchor:

$ printf 'line1\nline2\n' | sed '1s/^/PREFIX/'
PREFIXline1
line2

Use a to append lines after some line, and i to insert a line before another line. The a and i commands are not meant for modifying lines, just adding lines.

"Can this behavior be depended upon?" No. As Stéphane Chazelas points out in comments, "That's clearly a bug", and GNU sed does not show the described behaviour.


Regarding your question "If a line doesn't end in a newline character, is it still a line?", POSIX defines a "line" as

A sequence of zero or more non-<newline> characters plus a terminating <newline> character.

So the answer to that question is "no, it is not a line".

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.