Se você quiser simplesmente substituir todos os (
por [
e )
por ]
, não haverá necessidade de referências anteriores. Um simples tr
fará o trabalho:
$ tr '()' '[]' <file
[[23 + 5][23 + 5]]
11 x [2+1] = 11 x 3 = 33
3x[5+2]
ou, com sed
,
$ sed 'y/()/[]/' <file
[[23 + 5][23 + 5]]
11 x [2+1] = 11 x 3 = 33
3x[5+2]
Uma backreference só pode substituir algo existente na entrada por si mesma, por isso estou assumindo que você está pensando em tentar combinar as coisas entre os parênteses e depois substituí-las pelas mesmas coisas, mas entre colchetes. Você pode fazer isso com um loop:
$ sed -E -e ':loop' -e 's/\(([^()]+)\)/[]/; tloop' <file
[[23 + 5][23 + 5]]
11 x [2+1] = 11 x 3 = 33
3x[5+2]
Aqui, primeiro definimos um rótulo, loop
, e depois fazemos a nossa substituição. Se a substituição fez algo, então voltamos ao rótulo loop
. Precisamos fazer isso porque usar s/.../.../g
não encontrará correspondências sobrepostas e haverá sobreposição de correspondências assim que houver parênteses aninhados.
A substituição s/\(([^()]+)\)/[]/
encontrará qualquer string não vazia entre parênteses, que não contenha (
ou )
e substitua isso por si mesma, mas com os parênteses circundantes substituídos por colchetes.
Para a linha de entrada
((23 + 5)(23 + 5))
isso fará com que sed
execute a substituição quatro vezes:
-
([23 + 5](23 + 5))
, o primeiro parêntese interno é substituído. -
([23 + 5][23 + 5])
, depois o segundo interno. -
[[23 + 5][23 + 5]]
, depois o exterior. - A última substituição não fará nada e o loop sairá.
Usar o sinalizador g
no final da expressão de substituição fará com que as duas primeiras etapas acima sejam executadas na mesma substituição, pois elas não são sobrepostas.
Com expressões regulares básicas equivalentes (o acima usa uma expressão regular estendida para legibilidade):
sed -e ':loop' -e 's/(\([^()][^()]*\))/[]/; tloop' <file