Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

sed: -e expression #1, char 0: unmatched `{'

541 views
Skip to first unread message

hongy...@gmail.com

unread,
Dec 14, 2021, 5:37:39 AM12/14/21
to
Based on the trick given here [1], I tried with the following examples:

werner@X10DAi-00:~$ sed -E -e '/foo/ {s//bar/; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar
Unrelated
2nd foo
3rd foo
werner@X10DAi-00:~$ sed -E -e '/foo/ {a \ bar; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
sed: -e expression #1, char 0: unmatched `{'

As you can see, the 2nd fails. Any hints for fixing it?

[1] https://stackoverflow.com/a/33416489

Regards,
HZ

hongy...@gmail.com

unread,
Dec 14, 2021, 6:21:15 AM12/14/21
to
On Tuesday, December 14, 2021 at 6:37:39 PM UTC+8, hongy...@gmail.com wrote:
> Based on the trick given here [1], I tried with the following examples:
>
> werner@X10DAi-00:~$ sed -E -e '/foo/ {s//bar/; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
> 1st bar
> Unrelated
> 2nd foo
> 3rd foo
> werner@X10DAi-00:~$ sed -E -e '/foo/ {a \ bar; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
> sed: -e expression #1, char 0: unmatched `{'

To be more specific, see my following further testings:

werner@X10DAi-00:~$ sed -E -e '/foo/ {s//bar/;' -e ':c' -e '$!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar
Unrelated
2nd foo
3rd foo

werner@X10DAi-00:~$ sed -E -e '/foo/ {s//bar/; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar
Unrelated
2nd foo
3rd foo

werner@X10DAi-00:~$ sed -E -e '/foo/ {a \bar' -e ':c' -e '$!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st foo
bar
Unrelated
2nd foo
3rd foo

So, why can't I merge the script fragments introduced by `-e' into one for some cases?

Regards,
HZ

Ed Morton

unread,
Dec 14, 2021, 8:48:10 AM12/14/21
to
On 12/14/2021 4:37 AM, hongy...@gmail.com wrote:
> Based on the trick given here [1], I tried with the following examples:
>
> werner@X10DAi-00:~$ sed -E -e '/foo/ {s//bar/; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'

Why are you messing around with these horrifying sed incantations?
Whatever it is you're trying to do can be done some combination of more
clearly, efficiently, robustly, portably, etc. by using awk instead.
Literally since the mid 1980s if you're using sed constructs other than
s, g, and p (with -n) then you're using the wrong tool.

Ed.

Janis Papanagnou

unread,
Dec 14, 2021, 9:20:37 AM12/14/21
to
On 14.12.2021 11:37, hongy...@gmail.com wrote:
> Based on the trick given here [1], I tried with the following examples:
>
> werner@X10DAi-00:~$ sed -E -e '/foo/ {s//bar/; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
> 1st bar
> Unrelated
> 2nd foo
> 3rd foo
> werner@X10DAi-00:~$ sed -E -e '/foo/ {a \ bar; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
> sed: -e expression #1, char 0: unmatched `{'
>
> As you can see, the 2nd fails. Any hints for fixing it?

You seem to think that several -e arguments will be textually
concatenated. - Are you sure that is the case? (I don't know,
but wouldn't expect so.)

Where from is this defunct second call syntax that you posted
above?

From your answers to my two questions you can probably derive
the answer to your own question yourself.

Janis

hongy...@gmail.com

unread,
Dec 15, 2021, 12:29:46 AM12/15/21
to
On Tuesday, December 14, 2021 at 10:20:37 PM UTC+8, Janis Papanagnou wrote:
> On 14.12.2021 11:37, hongy...@gmail.com wrote:
> > Based on the trick given here [1], I tried with the following examples:
> >
> > werner@X10DAi-00:~$ sed -E -e '/foo/ {s//bar/; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
> > 1st bar
> > Unrelated
> > 2nd foo
> > 3rd foo
> > werner@X10DAi-00:~$ sed -E -e '/foo/ {a \ bar; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
> > sed: -e expression #1, char 0: unmatched `{'
> >
> > As you can see, the 2nd fails. Any hints for fixing it?
> You seem to think that several -e arguments will be textually
> concatenated. - Are you sure that is the case? (I don't know,
> but wouldn't expect so.)

I'm not sure, and that's my question: Sometimes they work, sometimes not by this concatenation.

> Where from is this defunct second call syntax that you posted
> above?

As you can see, I used `{` and `}` with matching numbers in the code. So, I really don't know where the problem comes from.

HZ


Geoff Clare

unread,
Dec 15, 2021, 9:11:07 AM12/15/21
to
Janis Papanagnou wrote:

> You seem to think that several -e arguments will be textually
> concatenated. - Are you sure that is the case? (I don't know,
> but wouldn't expect so.)

Here's what POSIX says:

If any -e or -f options are specified, the script of editing
commands shall initially be empty. The commands specified by
each -e or -f option shall be added to the script in the order
specified. When each addition is made, if the previous addition
(if any) was from a -e option, a <newline> shall be inserted
before the new addition.

The inserted <newline> is the important factor here.

--
Geoff Clare <net...@gclare.org.uk>

Helmut Waitzmann

unread,
Dec 15, 2021, 10:01:25 AM12/15/21
to
"hongy...@gmail.com" <hongy...@gmail.com>:
>werner@X10DAi-00:~$ sed -E -e '/foo/ {s//bar/; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
>1st bar
>Unrelated
>2nd foo
>3rd foo
>werner@X10DAi-00:~$ sed -E -e '/foo/ {a \ bar; :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
>sed: -e expression #1, char 0: unmatched `{'
>
>As you can see, the 2nd fails. Any hints for fixing it?
>

Read the 'sed' manual carefully (or should I say, cautious?),
especially the description of the 'a' command.  The POSIX manual of
the 'sed' utility might be helpful as well (see
<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html#tag_20_116_13_03>).

Or, try to answer the question:  How would you let the 'a' command
output a line ending with a semicolon?

Kenny McCormack

unread,
Dec 15, 2021, 11:08:26 AM12/15/21
to
In article <459p8i-...@ID-313840.user.individual.net>,
Geoff Clare <net...@gclare.org.uk> wrote:
>Janis Papanagnou wrote:
>
>> You seem to think that several -e arguments will be textually
>> concatenated. - Are you sure that is the case? (I don't know,
>> but wouldn't expect so.)
>
>Here's what POSIX says:

But they aren't really 'concatenated'; each has to internally complete.

Observe:

$ sed -e ifoo
blue
foo
blue
^C
$ sed -e i -e foo
sed: -e expression #1, char 1: expected \ after `a', `c' or `i'
$

--
The people who were, are, and always will be, wrong about everything, are still
calling *us* "libtards"...

(John Fugelsang)

Ben Bacarisse

unread,
Dec 15, 2021, 12:01:18 PM12/15/21
to
gaz...@shell.xmission.com (Kenny McCormack) writes:

> In article <459p8i-...@ID-313840.user.individual.net>,
> Geoff Clare <net...@gclare.org.uk> wrote:
>>Janis Papanagnou wrote:
>>
>>> You seem to think that several -e arguments will be textually
>>> concatenated. - Are you sure that is the case? (I don't know,
>>> but wouldn't expect so.)
>>
>>Here's what POSIX says:
>
> But they aren't really 'concatenated'; each has to internally
> complete.

Why did you start "but" and then snip the very clear explanation of
what's happening?

> Observe:
>
> $ sed -e ifoo
> blue
> foo
> blue
> ^C
> $ sed -e i -e foo
> sed: -e expression #1, char 1: expected \ after `a', `c' or `i'
> $

It would have been more helpful to say "yes" and give an example of how
the inserted newline makes multiple commands work:

$ echo xyz | sed -n -e '1=' -e '$='
1
1
$ echo xyz | sed -n -e '1=$='
sed: -e expression #1, char 3: extra characters after command
$ echo xyz | sed -n -e '1=
$='
1
1
$

--
Ben.

hongy...@gmail.com

unread,
Dec 15, 2021, 6:43:40 PM12/15/21
to
Good catch and wonderful example. But the content of echo doesn't matter here at all:

$ echo | sed -n -e '1=
$='
1
1

hongy...@gmail.com

unread,
Dec 15, 2021, 6:45:24 PM12/15/21
to
I looked through the POSIX manual of 'sed' you linked above, but still in the dark.

hongy...@gmail.com

unread,
Dec 15, 2021, 6:46:15 PM12/15/21
to
On Wednesday, December 15, 2021 at 10:11:07 PM UTC+8, Geoff Clare wrote:
> Janis Papanagnou wrote:
>
> > You seem to think that several -e arguments will be textually
> > concatenated. - Are you sure that is the case? (I don't know,
> > but wouldn't expect so.)
> Here's what POSIX says:

Where did you find these specifications?

hongy...@gmail.com

unread,
Dec 15, 2021, 7:00:16 PM12/15/21
to
On Thursday, December 16, 2021 at 7:46:15 AM UTC+8, hongy...@gmail.com wrote:
> On Wednesday, December 15, 2021 at 10:11:07 PM UTC+8, Geoff Clare wrote:
> > Janis Papanagnou wrote:
> >
> > > You seem to think that several -e arguments will be textually
> > > concatenated. - Are you sure that is the case? (I don't know,
> > > but wouldn't expect so.)
> > Here's what POSIX says:
> Where did you find these specifications?
> > If any -e or -f options are specified, the script of editing
> > commands shall initially be empty. The commands specified by
> > each -e or -f option shall be added to the script in the order
> > specified. When each addition is made, if the previous addition
> > (if any) was from a -e option, a <newline> shall be inserted
> > before the new addition.
> >

I find these specifications here: <https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html#tag_20_116_13_03>

Ben Bacarisse

unread,
Dec 15, 2021, 8:28:55 PM12/15/21
to
Except for clarity. echo on it's own echos a newline so the input to
sed has one empty line. In general, it's not a good idea to used
examples that have such hidden details. echo zyx obviously generates a
line. echo on it's own also does, but not it's not so obvious.

--
Ben.

hongy...@gmail.com

unread,
Dec 15, 2021, 10:59:13 PM12/15/21
to
On Thursday, December 16, 2021 at 9:28:55 AM UTC+8, Ben Bacarisse wrote:
> > $ echo | sed -n -e '1=
> > $='
> > 1
> > 1
> Except for clarity. echo on it's own echos a newline so the input to
> sed has one empty line. In general, it's not a good idea to used
> examples that have such hidden details. echo zyx obviously generates a
> line. echo on it's own also does, but not it's not so obvious.

Thank you for your additional explanation, I add the following example as a further example to improve your above point of view:

$ echo -e 'a\nb\nc' | sed -n -e '1=' -e '$='
1
3


Geoff Clare

unread,
Dec 16, 2021, 8:41:08 AM12/16/21
to
Kenny McCormack wrote:

> In article <459p8i-...@ID-313840.user.individual.net>,
> Geoff Clare <net...@gclare.org.uk> wrote:
>>Janis Papanagnou wrote:
>>
>>> You seem to think that several -e arguments will be textually
>>> concatenated. - Are you sure that is the case? (I don't know,
>>> but wouldn't expect so.)
>>
>>Here's what POSIX says:
>
> But they aren't really 'concatenated'; each has to internally complete.
>
> Observe:
>
> $ sed -e ifoo
> blue
> foo
> blue
> ^C
> $ sed -e i -e foo
> sed: -e expression #1, char 1: expected \ after `a', `c' or `i'
> $

I guess you missed the bit (that you didn't quote) of my post about
the inserted <newline>.

sed -e i -e foo

would be equivalent to:

sed -e 'i
foo'

which is invalid. Whereas the equivalent of the valid command:

sed -e 'i\
foo'

split into two -e option-arguments is:

sed -e 'i\' -e foo

and works fine:

$ echo blue | sed -e 'i\' -e foo
foo
blue

--
Geoff Clare <net...@gclare.org.uk>

Helmut Waitzmann

unread,
Dec 16, 2021, 6:20:09 PM12/16/21
to
"hongy...@gmail.com" <hongy...@gmail.com>:
Ok.  Do you understand the English language?  Then, please, read
the following quote from the POSIX manual linked above:

'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.'

What is the implication of this sentence in combination with the
whole section of the POSIX manual linked above with regard to the
'a' command?  Yes:  The 'a' command CANNOT BE FOLLOWED BY A
SEMICOLON…

Now, look at your testing above:  What are you doing there?


Sorry, but this is basic language understanding.  If you don't obey
the rules, you shouldn't be surprised when they strike back.

hongy...@gmail.com

unread,
Dec 16, 2021, 8:53:40 PM12/16/21
to
I just browse the entire content linked by you with searching the literal `;' instead of trying to find the wording `<semicolon>' used there. This makes it impossible for me to quickly find the explanation you pointed out above.


> Now, look at your testing above: What are you doing there?

But with or without the `;', the same error will be triggered:

$ 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 `{'

> Sorry, but this is basic language understanding. If you don't obey
> the rules, you shouldn't be surprised when they strike back.

Agree. That should be the expected behavior, if so.

Oğuz

unread,
Dec 17, 2021, 12:02:38 AM12/17/21
to
On 12/17/21 4:53 AM, hongy...@gmail.com wrote:
> But with or without the `;', the same error will be triggered:
>
> $ 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 `{'

The `a\' command needs to be terminated with a line break, not a blank
or a semicolon you moron.


$ sed -E -e '/foo/ {a \ bar
> :c $!{n;bc}}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st foo
bar
Unrelated
2nd foo
3rd foo
$

hongy...@gmail.com

unread,
Dec 17, 2021, 3:27:39 AM12/17/21
to
Thank you for pointing this out. I didn't realize that the command format in the manual page already contained the usage information you mentioned above:

$ man sed | grep -A2 ' \\$' | grep -v '^--'
a \

text Append text, which has each embedded newline preceded by a backslash.
i \

text Insert text, which has each embedded newline preceded by a backslash.
c \

text Replace the selected lines with text, which has each embedded newline preceded by a backslash.

So, all the above three commands need to be terminated with a line break.

HZ

Helmut Waitzmann

unread,
Dec 17, 2021, 3:36:45 PM12/17/21
to
"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.)

hongy...@gmail.com

unread,
Dec 17, 2021, 11:23:56 PM12/17/21
to
Thank you for providing insightful and wonderful examples and explanations.

HZ
0 new messages