Re: Document another portability pitfall of sed

Nick Bowler <[email protected]> Tue, 24 Jun 2025 15:20:09 -0400
Newsgroups gmane.comp.sysutils.autoconf.patches
Message-ID <ufsp7vc4rv5uh4hubwygmmtfxu54pw725qd26pr53suft556kc@5sgbpmsv4uev>
On Mon, Jun 23, 2025 at 11:36:19PM +0200, Bruno Haible via Patches for autoconf - the GNU build system wrote:
> With GNU sed:
> 
> $ echo foo | sed -e 's/f.*/line1\nline2/'
> line1
> line2
> 
> Even in strict POSIX mode:
> 
> $ echo foo | POSIXLY_CORRECT=1 sed --posix -e 's/f.*/line1\nline2/'
> line1
> line2
> 
> Whereas with OpenBSD sed and Solaris 11.4 sed:
> 
> $ echo foo | sed -e 's/f.*/line1\nline2/'
> line1nline2
> 
> Here's a proposed patch to update the Autoconf documentation.
> 
> Note: I think POSIX [1] mandates the behaviour of OpenBSD and Solaris sed.
> But that is not immediately relevant for the Autoconf manual: The portability
> problem exists regardless of how we might interpret POSIX.

The GNU behaviour is likely non-conforming with Issue 5 (1997) and
earlier specifications, but since Issue 6 (2001) the meaning of \n in
the replacement string is explicitly unspecified.  So both behaviours
are POSIX-compliant nowadays.

> +In the replacement text of an @samp{s}, it is not portable to use
> +escape sequences like @samp{\n}.  While GNU @command{sed} interprets
> +them, the @command{sed} commands of OpenBSD and Solaris don't.

It would probably be helpful to mention that the POSIX-standard and
portable method to substitute a newline with sed is to use backslash-
newline.  For example:

% echo foo | sed 's/f.*/line1\
line2/'
line1
line2

Cheers,
  Nick