Регулярные выражения Sed соответствуют самому длинному совпадению. Сед не имеет эквивалента не жадных.
Очевидно, что мы хотим сделать, это матч
AB
с
последующим
- любое количество чего-либо кроме
AC
,
сопровождаемого
AC
К сожалению, sed
не могу сделать # 2 - по крайней мере, не для многосимвольного регулярного выражения. Конечно, для односимвольного регулярного выражения, такого как @
(или даже [123]
), мы можем сделать [^@]*
или [^123]*
. И поэтому мы можем обойти ограничения СЕПГА путем изменений всех вхождений AC
в , @
а затем в поисках
AB
с
последующим
- любое количество чего-либо кроме
@
,
сопровождаемого
@
как это:
sed 's/AC/@/g; s/AB[^@]*@/XXX/; s/@/AC/g'
Последняя часть изменяет непревзойденные экземпляры @
обратно на AC
.
Но, конечно, это безрассудный подход, потому что входные данные уже могут содержать @
символы, поэтому, сопоставляя их, мы можем получить ложные срабатывания. Однако, поскольку ни одна переменная оболочки никогда не будет содержать символ NUL ( \x00
), NUL, вероятно, является хорошим символом для использования в вышеуказанном обходном пути вместо @
:
$ echo 'ssABteAstACABnnACss' | sed 's/AC/\x00/g; s/AB[^\x00]*\x00/XXX/; s/\x00/AC/g'
ssXXXABnnACss
Использование NUL требует GNU sed. (Чтобы убедиться, что функции GNU включены, пользователь не должен устанавливать переменную оболочки POSIXLY_CORRECT.)
Если вы используете sed с -z
флагом GNU для обработки входных данных, разделенных NUL, таких как выходные данные find ... -print0
, то NUL не будет в пространстве шаблонов, и NUL является хорошим выбором для подстановки здесь.
Хотя NUL не может быть в переменной bash, его можно включить в printf
команду. Если ваша входная строка может содержать какой-либо символ, включая NUL, см. Ответ Стефана Шазеласа, в котором добавлен умный метод экранирования.