As expressões regulares de sed correspondem à correspondência mais longa. Sed não tem equivalente de não ganancioso.
Obviamente, o que queremos fazer é combinar
-
AB
,
seguido por - qualquer quantidade diferente de
AC
,
seguido por -
AC
Infelizmente, sed
não pode fazer # 2 -
pelo menos não para uma expressão regular de vários caracteres. Claro,
para uma expressão regular de caractere único, como @
(ou mesmo [123]
),
nós podemos fazer [^@]*
ou [^123]*
.
E assim podemos contornar as limitações do sed
alterando todas as ocorrências de AC
para @
e pesquisando
-
AB
,
seguido por - qualquer número diferente de
@
,
seguido por -
@
assim:
sed 's/AC/@/g; s/AB[^@]*@/XXX/; s/@/AC/g'
A última parte muda instâncias não correspondidas de @
de volta para AC
.
Mas, claro, essa é uma abordagem imprudente,
porque a entrada já pode conter @
caracteres,
então, combinando-os, poderíamos obter falsos positivos. Contudo,
já que nenhuma variável shell terá um caractere NUL ( \x00
), o NUL provavelmente é um bom caractere para ser usado na solução alternativa acima, em vez de @
:
$ echo 'ssABteAstACABnnACss' | sed 's/AC/\x00/g; s/AB[^\x00]*\x00/XXX/; s/\x00/AC/g'
ssXXXABnnACss
O uso de NUL requer o GNU sed. (Para ter certeza de que os recursos GNU estão habilitados, o usuário não deve ter definido a variável shell POSIXLY_CORRECT.)
Se você estiver usando sed com o flag -z
do GNU para lidar com entradas separadas por NUL, como a saída de find ... -print0
, então NUL não estará no espaço padrão e NUL é uma boa escolha para a substituição aqui.
Embora o NUL não possa estar em uma variável bash, é possível incluí-lo em um comando printf
. Se sua string de entrada puder conter qualquer caractere, incluindo o NUL, veja a resposta de Stéphane Chazelas , que adiciona um caracter inteligente método de escape.