help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sed: Invalid content of \{\}


From: Davide Brini
Subject: Re: sed: Invalid content of \{\}
Date: Sun, 18 Apr 2021 18:41:34 +0200

On Sun, 18 Apr 2021 18:18:32 +0200, michael-franzese@gmx.com wrote:

>
>
> Am trying to capture tho string within {}, but am getting
>
> sed: -e expression #1, char 19: Invalid content of \{\}
> sed: -e expression #1, char 19: Invalid content of \{\}
> sed: -e expression #1, char 19: Invalid content of \{\}
>
>
> a="{12..30..5}"
> fa=`echo $a | sed 's/.*(\{.*\}).*/\1/g'`

(I'm not commenting on the shell syntax issues)

By default, sed uses BREs (Basic Regular Expressions), a somewhat old
flavour which almost no other tool or language uses nowadays (the most
notable, besides sed, being grep, another old command).

In BRE, the braces are NOT special when used unescaped, and are special
when escaped, in which case they act as quantifiers (eg, "a\{3,5\}" matches
between 3 and 5 a's). So, since you're escaping them, sed expects them to
follow the quantifier syntax and contain numbers indicating how many times
the preceding atom should be matched, but you're leaving them empty.

But you want the braces to match literally, so you should not escape them:

a="{12..30..5}"
fa=`echo $a | sed 's/.*({.*}).*/\1/g'`

This still has a problem: from the \1 in the right hand side (and from the
text of your message!), it can be inferred that you want the round brackets
on the left side to capture the match. In BREs, that is done by _escaping_
them, so you really want:

a="{12..30..5}"
fa=`echo $a | sed 's/.*\({.*}\).*/\1/g'`

Now that I've managed to confuse you, let me add that to avoid the
admittedly somewhat backwards syntax of BRE (at least compared to what
we're used to nowadays), most sed implementations support the use of
Extended Regular Expressions (EREs), where your original syntax does
exactly what you meant it to do. In most cases (for example with GNU sed),
EREs are enabled using the -E switch, so here's an example:

a="{12..30..5}"
fa=`echo $a | sed -E 's/.*(\{.*\}).*/\1/g'`


--
D.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]