Joining lines with POSIX sed

That's a job for paste:

printf '%s\n' a b c | paste -sd '\0' -

(no, that's not joining with NULs, that's joining with no separator as required by POSIX. Some paste implementations also support paste -sd '' - but that's neither standard nor portable).

Note that except in the busybox implementation, it produces one empty line as output if the input is empty (a historical bug/misfeature unfortunately now engraved in the POSIX specification).

With POSIX sed:

sed -e :a -e '$!{N;ba' -e '}' -e 's/\n//g'

Or:

sed '
:a
$!{
  N
  ba
}
s/\n//g'

The b, :, and } commands cannot be followed by another command. In earlier versions of the POSIX specification, b a;s/a/b/ would require b to branch to the label called a;s/a/b/, in newer versions of the specification, it's now unspecified, to allow the GNU sed behaviour. The following command has to be in a subsequent expression or on a separate line.

Also POSIX requires N on the last line to exit without printing the pattern space. GNU sed only does it in POSIX mode, like when there's a POSIXLY_CORRECT variable in the environment or with your --posix option which explains why you get no output with --posix.

Also note that the minimum size of the pattern space guaranteed by POSIX is 8192 bytes. You can only use that approach portably for very small files. paste has no size limitation, and contrary to the sed approach doesn't need to load the whole file in memory before printing it.

Another approach is tr -d '\n'. However note that contrary to paste/sed, it produces a non-delimited line on output (outputs abc instead of abc\n on the example above).

In any case, <<< is a zsh operator (now supported by a few other shells), and $'...' is a ksh93 operator (now supported by most other POSIX-like shells), neither are POSIX sh operators (though the latter is likely to be added to the next major revision of the standard), so should not be used in POSIX sh scripts.


With any awk in any shell on every UNIX box for any size input file (unless that input file is just 1 massive line of text containing no spaces that can't fit in memory):

$ printf '%s\n' a b c | awk -v ORS= '1; END{if (NR) print RS}'
abc