sed,posix,options – Difference Between ‘sed -e’ and Using Semicolons for Multiple Commands

optionsposixsed

I am perhaps picking nits here, but it would be really good to have this question that's been bothering me answered once and for all…

Text file for reprex:

Line one.
Line two.

Line three.
Line four.

To add an additional empty line consistently to this text file would require two sed commands for each line. This could be achieved with any of the following syntaxes:

  1. sed -e '/^$/d' -e '$!G' <file>… but NOT (sed -e '/^$/d' '$!G' <file> OR sed '/^$/d' '$!G' <file>)
  2. sed -e '/^$/d; $!G' <file> or sed -e '/^$/d ; $!G' <file>
  3. sed '/^$/d; $!G' <file> or sed '/^$/d ; $!G' <file>

My questions are:

  1. Is there any real difference (universality?, compliance?…) between any of the five working syntaxes listed above?
  2. Richard Blum's Latest Command Line And Shell Scripting Bible says to use something like sed -e 's/brown/red/; s/dog/cat/' data1.txt before doling out the following advice…

The commands must be separated with a semicolon (;), and there
shouldn't be any spaces between the end of the first command and the
semicolon.

…and then goes on to completely neglect his own advice by not using the -e option at all and also adding spaces between the end of a command and the semicolon (like shown in the second variant of the #3 above).. So, does the spacing around the semicolon make any real difference, at all?

  1. Although I couldn't find info on this in the manpage or documentation, my hunch is that the -e option is meant to be used as shown in syntax number #1 above, and using both -e and ; on the command line is redundant. Am I correct?

EDIT: I should have mentioned this in my original question to make it more specific; but as some people have already pointed out, these nuances would matter when using branch (b) or test (t) commands. But it's interesting to note the other cases when these would make a difference. Thanks!

Best Answer

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.

Related Question