Remove everything between pairs of curly braces with sed

I have a line 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 substrings matching %{...} , which may or may not contain additional 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 that do not contain %{...} . It is not suitable for strings like %{%B%F{blue}%} (it returns %} ).

I want to parse the string until I find the appropriate one } , and then delete everything to this point, and not delete everything between %{ and the first } that I encounter. I am not sure how to do this.

I fully understand that there are several ways to do this; I would prefer the answer to the question that is indicated in the question, if possible, but any ideas are more than welcome.

+4
source share
3 answers

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 *] 
+1
source

Use recursion to eat it from the inside.

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

Then wrap in

 while(there at least one more brace) 

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

0
source

Try the following:

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

Source: https://habr.com/ru/post/1412086/


All Articles