simont
simont

Reputation: 72527

Remove everything between pairs of braces with sed

I've got a string that looks like this:

[%{%B%F{blue}%}master %{%F{red}%}*%{%f%k%b%}%{%f%k%b%K{black}%B%F{green}%}]

I want to remove the substrings matching %{...}, which may or may not contain further substrings of the same order.

I should get: [master *] as the final output. My progress so far:

gsed -E 's/%\{[^\}]*\}//g'

which gives:

echo '[%{%B%F{blue}%}master %{%F{red}%}*%{%f%k%b%}%{%f%k%b%K{black}%B%F{green}%}]' | gsed -E 's/%\{[^\}]*\}//g'
[%}master %}*%B%F{green}%}]

So, this works fine for %{...} sections which do not contain %{...}. It fails for strings like %{%B%F{blue}%} (it returns %}).

What I want to do is parse the string until I find the matching }, then remove everything up to that point, rather than removing everything between %{ and the first } I encounter. I'm not sure how to do this.

I'm fully aware that there are probably multiple ways to do this; I'd prefer an answer regarding the way specified in the question if it is possible, but any ideas are more than welcome.

Upvotes: 4

Views: 1616

Answers (3)

Tyilo
Tyilo

Reputation: 30102

Try this:

sed -E 's/%{([^{}]*({[^}]*})*[^{}]*)*}//g'

Upvotes: 0

potong
potong

Reputation: 58351

This might work for you:

echo '[%{%B%F{blue}%}master %{%F{red}%}*%{%f%k%b%}%{%f%k%b%K{black}%B%F{green}%}]' |
sed 's/%{/{/g;:a;s/{[^{}]*}//g;ta'
[master *]

Upvotes: 1

djechlin
djechlin

Reputation: 60748

Use recursion to eat it out from the inside out.

s/%{.*?%}//g

Then wrap in

while(there's at least one more brace)

(probably while $? -ne 0 ... whatever rcode sed uses to say "no matches!")

Upvotes: 0

Related Questions