Difference between 'sed -e' and delimiting multiple commands with semicolon
Let us use the Sed POSIX standard to answer the questions.
Does the spacing around the semicolon make any real difference?
Editing commands other than {...}, a, b, c, i, r, t, w, :, and # can be followed by a semicolon, optional blank characters, and another editing command.
Thus /^$/d ; $!G
is not compliant, but /^$/d; $!G
is. But I do wonder if
there is any modern Sed implementation that would stumble on that.
Is there any real difference (universality, compliance...) between any of the three syntaxes listed above?
No (except for the one with spaces before the semicolon, as argued above). This is clear in the synopsis:
sed [-n] script [file...] sed [-n] -e script [-e script]... [-f script_file]... [file...]
Do note, however, that as the previous quote mentioned, some commands cannot be followed by a semicolon, and then
sed -e ':a' -e 's/x/y/' -e 't a'
is compliant, while
sed ':a;s/x/y;t a'
is not, although but work the same at least in GNU Sed.
My hunch is that (...) using both -e
and ;
on the command line is redundant. Am I correct?
If you refer to the examples in the question, yes. If there is a single -e
option, then just drop it and it is all the same (unless you also use the
-f
option (see the synopsis)). But in
sed -e ':a' -e 's/x/y;t a'
both -e
and ;
are present but they are not redundant.
It does matter for a few commands.
In the original sed
implementations, : foo;bar
, b foo;bar
, t foo;bar
respectively define, branch, conditionally-branch to the foo;bar
label.
It even used to be required by POSIX (I was the one asking for the requirement to be relaxed).
w foo;bar
and r foo;bar
are still to write/read to/from the foo;bar
file in all conforming implementations.
The #
command (for comments), a
, i
, c
(append, insert, change) can obviously not be followed by another command on the same line.
Historical sed
implementations don't support }
being followed by another command either.
POSIX used to say you couldn't have a ;
before }
though that wasn't needed in practice (I also asked for that requirement to be relaxed).
sed -e cmd1 -e cmd2
is meant to be equivalent to
sed -e 'cmd1
cmd2'
But in practice that's not the case in all implementations when it comes to:
sed -e 'a\' -e 'foo\' -e 'bar'
sed -e 's/foo/bar\' -e 'baz/g'
for instance.