Subject: Re: bug#21845: sed docs bug: No documentation of which commands must be terminated by newlines

From: Assaf Gordon <[email-masked]>
Date: Wed, 25 Jan 2017 03:51:51 +0000

Hello Ori,

Sorry for the delayed response.

On Fri, Nov 06, 2015 at 05:44:04PM +0200, Ori Avtalion wrote:
>Some commands, due to their syntax, cannot be followed by semicolons
>[...]
>I can find no mention of which commands this applies to.
>This limitation should be mentioned next to each such command.

Thank you for mentioning this. Indeed an important piece of information.

I'm considering adding a new section about this.
Draft attached, comments welcomed.

>The documentation uses 'file-name' instead of 'filename'.

Fixed as well.

regards,
 - assaf
>From 079f3409b60782d5a4b1da678fa5831ea9c8a01f Mon Sep 17 00:00:00 2001
From: Assaf Gordon <[email-masked]>
Date: Wed, 25 Jan 2017 03:41:59 +0000
Subject: [PATCH] doc: new 'multiple commands syntax' section

Explain which commands can be separated by semicolon and which require
newlines. Requested by Ori Avtalion in https://bugs.gnu.org/21845 .

* doc/sed.texi (Multiple commands syntax): New section in "sed scripts"
chapter.
---
 doc/sed.texi | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 232 insertions(+), 3 deletions(-)

diff --git a/doc/sed.texi b/doc/sed.texi
index c45b150..36953a3 100644
--- a/doc/sed.texi
+++ b/doc/sed.texi
@@ -484,6 +484,7 @@ $ echo | sed 'Q42' ; echo $?
 * Other Commands::           Less frequently used commands
 * Programming Commands::     Commands for @command{sed} gurus
 * Extended Commands::        Commands specific of @value{SSED}
+* Multiple commands syntax:: Extnesion for easier scripting
 @end menu
 
 @node sed script overview
@@ -586,6 +587,7 @@ thus should be terminated
 with newlines or be placed at the end of a @var{script} or @var{script-file}.
 Commands can also be preceded with optional non-significant
 whitespace characters.
+@xref{Multiple commands syntax}.

@@ -903,12 +905,12 @@ while in general flags for the @code{s} command show their
 effect just once.  This behavior, although documented, might
 change in future versions.
 
-@item w @var{file-name}
+@item w @var{filename}
 @cindex Text, writing to a file after substitution
 @cindex @value{SSEDEXT}, @file{/dev/stdout} file
 @cindex @value{SSEDEXT}, @file{/dev/stderr} file
 If the substitution was made, then write out the result to the named file.
-As a @value{SSED} extension, two special values of @var{file-name} are
+As a @value{SSED} extension, two special values of @var{filename} are
 supported: @file{/dev/stderr}, which writes the result to the standard
 error, and @file{/dev/stdout}, which writes to the standard
 output.@footnote{This is equivalent to @code{p} unless the @option{-i}
@@ -1464,7 +1466,7 @@ file will then be reread and inserted on each of the addressed lines.
 @cindex @value{SSEDEXT}, @file{/dev/stdout} file
 @cindex @value{SSEDEXT}, @file{/dev/stderr} file
 Write the pattern space to @var{filename}.
-As a @value{SSED} extension, two special values of @var{file-name} are
+As a @value{SSED} extension, two special values of @var{filename} are
 supported: @file{/dev/stderr}, which writes the result to the standard
 error, and @file{/dev/stdout}, which writes to the standard
 output.@footnote{This is equivalent to @code{p} unless the @option{-i}
@@ -1706,7 +1708,234 @@ script in most multibyte locales (including UTF-8 locales).
 @end table

+@node Multiple commands syntax
+@section Multiple commands syntax
+
+@c POSIX says:
+@c   Editing commands other than {...}, a, b, c, i, r, t, w, :, and #
+@c   can be followed by a <semicolon>, optional <blank> characters, and
+@c   another editing command. However, when an s editing command is used
+@c   with the w flag, following it with another command in this manner
+@c   produces undefined results.
+
+There are several methods to specify multiple commands in a @command{sed}
+program.
+
+Using newlines is most natural when running sed script from a file
+(using @option{-f} option).
+
+On the command line, all @command{sed} commands can be separated by a
+newline, or with multiple @option{-e} parameters:
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ seq 6 | sed '1d
+3d
+5d'
+2
+4
+6
 
+$ seq 6 | sed -e 1d -e 3d -e 5d
+2
+4
+6
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+Most simple commands can be separated by a semicolon (@samp{;}):
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ seq 6 | sed '1d;3d;5d'
+2
+4
+6
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+The @code{@{},@code{@}},@code{b},@code{t},@code{T},@code{:} commands can
+be separated with a semicolon (this is a non-portable @value{SSED} extension).
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ seq 4 | sed '@{1d;3d@}'
+2
+4
+
+$ seq 6 | sed '@{1d;3d@};5d'
+2
+4
+6
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+Labels used in @code{b},@code{t},@code{T},@code{:} commands are read
+until the semicolon. Leading and trailing whitespaces are ignored.  In
+the examples below the label is @samp{x}.  The first example works
+with @value{SSED}. The second is a portable equivalent.  For more
+information about branching and labels @pxref{Branching and flow
+control}.
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ seq 3 | sed '/1/b x ; s/^/=/ ; :x ; 3d'
+1
+=2
+
+$ seq 3 | sed -e '/1/bx' -e 's/^/=/' -e ':x' -e '3d'
+1
+=2
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+
+
+@subsection Commands Requiring a newline
+
+The following commands cannot be separated by a semicolon and
+require a newline:
+
+@table @asis
+
+@item @code{a},@code{c},@code{i} (append/change/insert)
+
+All characters following @code{a},@code{c},@code{i} commands are taken
+as the text to append/change/insert. Using a semicolon leads to
+undesirable results:
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ seq 2 | sed '1aHello ; 2d'
+1
+Hello ; 2d
+2
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+Separate the commands using @option{-e} or a newline:
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ seq 2 | sed -e 1aHello -e 2d
+1
+Hello
+
+$ seq 2 | sed '1aHello
+2d'
+1
+Hello
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+Note that specifing the text to add (@samp{Hello}) immediately
+after @code{a},@code{c},@code{i} is itself a @value{SSED} extension.
+A portable, POSIX-compliant alternative is:
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ seq 2 | sed '1a\
+Hello
+2d'
+1
+Hello
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+@item @code{#} (comment)
+
+All characters following @samp{#} until the next newline are ignored.
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ seq 3 | sed '# this is a comment ; 2d'
+1
+2
+3
+
+
+$ seq 3 | sed '# this is a comment
+2d'
+1
+3
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+@item @code{r},@code{R},@code{w},@code{W} (reading and writing files)
+
+The @code{r},@code{R},@code{w},@code{W} commands parse the filename
+until end of the line. If whitespace or semicolons are found, they will
+be included in the filename, leading to unexpected results:
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ seq 2 | sed '1w hello.txt ; 2d'
+1
+2
+
+$ ls -log
+total 4
+-rw-rw-r-- 1 2 Jan 23 23:03 hello.txt ; 2d
+
+$ cat 'hello.txt ; 2d'
+1
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+Note that @command{sed} silently ignores read/write errors in
+@code{r},@code{R},@code{w},@code{W} commands (such as missing files).
+In the following example, @command{sed} tries to read a file named
+@samp{@file{hello.txt ; N}}. The file is missing, and the error is silently ignored:
+
+@codequoteundirected on
+@codequotebacktick on
+@example
+@group
+$ echo x | sed '1rhello.txt ; N'
+x
+@end group
+@end example
+@codequoteundirected off
+@codequotebacktick off
+
+
+@end table

 @node sed addresses
-- 
1.9.0