Les expressions régulières sed correspondent à la plus longue correspondance. Sed n'a pas d'équivalent de non gourmand.
Évidemment, ce que nous voulons faire, c'est
AB
,
suivi de
- tout montant autre que
AC
,
suivi de
AC
Malheureusement, sed
ne peut pas faire # 2 - du moins pas pour une expression régulière à plusieurs caractères. Bien sûr, pour une expression régulière à un seul caractère comme @
(ou même [123]
), nous pouvons faire [^@]*
ou [^123]*
. Et donc nous pouvons contourner les limites de sed en changeant toutes les occurrences de AC
en @
puis en recherchant
AB
,
suivi de
- tout autre chose que
@
,
suivi de
@
comme ça:
sed 's/AC/@/g; s/AB[^@]*@/XXX/; s/@/AC/g'
La dernière partie @
remplace les instances inégalées de back to AC
.
Mais, bien sûr, c'est une approche imprudente, car l'entrée peut déjà contenir des @
caractères, donc, en les faisant correspondre, nous pourrions obtenir des faux positifs. Cependant, étant donné qu'aucune variable shell n'aura jamais de caractère NUL ( \x00
), NUL est probablement un bon caractère à utiliser dans la solution de contournement ci-dessus au lieu de @
:
$ echo 'ssABteAstACABnnACss' | sed 's/AC/\x00/g; s/AB[^\x00]*\x00/XXX/; s/\x00/AC/g'
ssXXXABnnACss
L'utilisation de NUL nécessite GNU sed. (Pour vous assurer que les fonctionnalités GNU sont activées, l'utilisateur ne doit pas avoir défini la variable shell POSIXLY_CORRECT.)
Si vous utilisez sed avec l' -z
indicateur GNU pour gérer les entrées séparées par NUL, telles que la sortie de find ... -print0
, alors NUL ne sera pas dans l'espace de motif et NUL est un bon choix pour la substitution ici.
Bien que NUL ne puisse pas être dans une variable bash, il est possible de l'inclure dans une printf
commande. Si votre chaîne d'entrée peut contenir n'importe quel caractère, y compris NUL, alors voyez la réponse de Stéphane Chazelas qui ajoute une méthode d'échappement intelligente.