Удалите все между парами фигурных скобок с помощью sed

4 simont [2012-05-12 00:23:00]

У меня есть строка, которая выглядит так:

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

Я хочу удалить подстроки, соответствующие %{...}, которые могут содержать или не содержать дополнительные подстроки того же порядка.

Я должен получить: [master *] как окончательный вывод. Мой прогресс до сих пор:

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

который дает:

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}%}]

Итак, это отлично работает для разделов %{...}, которые не содержат %{...}. Он не подходит для строк типа %{%B%F{blue}%} (он возвращает %}).

Я хочу сделать синтаксический анализ строки до тех пор, пока не найду соответствующий }, а затем удалю все до этой точки, а не удалю все между %{ и первым }, с которым я сталкиваюсь. Я не уверен, как это сделать.

Я полностью понимаю, что существует несколько способов сделать это; Я бы предпочел ответ на вопрос, который указан в вопросе, если это возможно, но любые идеи более чем приветствуются.

regex sed


3 ответа


1 Решение potong [2012-05-12 00:44:00]

Это может сработать для вас:

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 *]

0 djechlin [2012-05-12 00:33:00]

Используйте рекурсию, чтобы съесть ее изнутри.

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

Затем заверните в

while(there at least one more brace)

(возможно, в то время как $? -ne 0... все, что rcode sed использует, чтобы сказать "нет совпадений!" )


0 Tyilo [2012-05-12 01:01:00]

Попробуйте следующее:

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