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.