Я не понимаю, как это могло выполняется с помощью только sed, поскольку обычные регулярные выражения не должны быть в состоянии соответствовать вложенным круглым скобкам . К счастью, такие вещи, как Perl, также поддерживают не очень регулярные выражения, вроде этого, украденного из ответа здесь :
echo "out side (in ( side ( ) ) remove ( spaces ) ) out ( in again )." |
perl -lpe 's/\(([^()]|(?R))*\)/ local $_ = $&; s,\s+,,g; $_ /eg'
out side (in(side())remove(spaces)) out (inagain).
(Не) регулярное выражение работает следующим образом:
\(([^()]+|(?R))*\)
^^| | ||^^ -- literal parenthesis, inside of which:
^ ^ ^| --- group with choice:
^^^^^^ ^^^^ | ---- anything except parenthesis, any number,
| OR this whole pattern again.
^ ----- any number of those two choices
Заменяющая часть принимает соответствие строка из $ &
, изменяет ее в локальной переменной, удаляя все символы пробела, и возвращает измененное значение. ( s ///
не работает напрямую с $ &
или $ 1
.)
Хотя это проще, если вы знаете, что у вас есть только один набор круглые скобки в одной строке, поэтому может соответствовать от первого (
до последнего )
.
echo "out (in ( side) here ) out again." |
perl -pe 's/\(.*\)/ $_ = $&; s,\s+,,g; $_ /e'
out (in(side)here) out again.
Заявление об ограничении ответственности: я не знаю, может ли использование $ _
внутри s /// e
сломаться, но, похоже, у меня это работает.