Регулярные выражения 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, см. Ответ Стефана Шазеласа, в котором добавлен умный метод экранирования.