"
hongy...@gmail.com" <
hongy...@gmail.com>:
That's true, indeed. It's the difference between browsing and
(carefully) reading.
But I didn't want you to search the text for semicolons (neither
the symbol nor the word). I supposed, that you either read the
given section of the manual or (without reading the manual) just
asked yourself the question: How would one let the 'a' command
output a line ending with a semicolon?
To answer that question: The developers of the 'sed' program were
quite silly, if they had designed an 'a' command in such a way,
that it were not possible to let it output a line ending with a
semicolon.
The consequence of this statement is, that the 'a' command cannot
look like this example:
a \ This is a line to be appended, ending in a period.;
i. e. the semicolon cannot be used as an 'a' command terminator,
as that would it make impossible to have a semicolon be part of a
line to be appended by the 'a' command.
And at this point you could indeed read the manual. For to make
your life easier, I gave you a link with an anchor (i. e. the
'#tag_20_116_13_03' part of the URL), which should position your
browser at the relevant section of the manual.
That's, what I called reading the manual carefully or even
cautiously.
>
>
>> Now, look at your testing above: What are you doing there?
>>
To give the answer: Your example assumes, that a semicolon can be
used as an 'a' command terminator. The consequence of this is, that
you assume, that the developers of the 'sed' program where quite
silly when designing the 'a' command.
>
> But with or without the `;', the same error will be triggered:
>
That's by coincidence, just like switching the christmas tree
lights on won't work regardless of the colors of the bulbs if the
fuse has been burnt out.
The problem in your example is not the semicolon (be it present or
not); it's the missing newline after the intended 'a' command,
which will let the 'a' command continue til the end of the 'sed'
invocation argument. Therefore even the two '}' will be part of
the 'a' command, "eating" the '}' that was intended to match the
'{' immediately preceding the 'a' command, thus leaving the '{'
unmatched:
> $ sed -E -e '/foo/ {a \ bar; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
> sed: -e expression #1, char 0: unmatched `{'
>
> $ sed -E -e '/foo/ {a \ bar :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
> sed: -e expression #1, char 0: unmatched `{'
>
To see a difference with or without the first semicolon in the
invocation argument, add a newline and the missing '}' to each
variant to make it a syntactically valid 'sed' script. Run the two
variants:
printf '%s\n' '1st foo' 'Unrelated' '2nd foo' '3rd foo' |
sed -E -e '/foo/ {a \ bar; :c $!{n;bc}}
}'
printf '%s\n' '1st foo' 'Unrelated' '2nd foo' '3rd foo' |
sed -E -e '/foo/ {a \ bar :c $!{n;bc}}
}'
(I prefer the posixly 'printf' over the not‐yet‐posixly shell
syntax $'…' and the posixly pipeline over non‐posixly here‐strings
(<<<) to have the examples work with any posixly environment.)