Це як надійно виконати не жадібну відповідність багато символьних рядків за допомогою sed. Припустимо , ви хочете змінити кожен , foo...barщоб <foo...bar>так, наприклад , цей вхід:
$ cat file
ABC foo DEF bar GHI foo KLM bar NOP foo QRS bar TUV
повинен стати таким результатом:
ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV
Для цього ви перетворюєте колонтитул і смугу в окремі символи, а потім використовуєте заперечення цих символів між ними:
$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/g; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV
У вищесказаному:
s/@/@A/g; s/{/@B/g; s/}/@C/gперетворює {і }в рядки заповнювачів, які не можуть існувати на вході, тому ці символи потім доступні для перетворення fooтаbar в.
s/foo/{/g; s/bar/}/gперетворюється fooі barв {і} відповідно
s/{[^{}]*}/<&>/gвиконує оп, який ми хочемо - перетворюємо foo...barна<foo...bar>
s/}/bar/g; s/{/foo/gперетворюється {і }повертається до fooтаbar .
s/@C/}/g; s/@B/{/g; s/@A/@/g перетворює рядки заповнювача у свої початкові символи.
Зауважте, що вищезгадане не покладається на те, що якась конкретна рядок не присутня на вході, оскільки вона виробляє такі рядки на першому кроці, і не дбає про те, яке виникнення конкретного повторного виклику ви хочете відповідати, оскільки ви можете використовувати {[^{}]*}стільки разів, скільки потрібно в виразі, щоб виділити фактичну відповідність, яку ви хочете, та / або з оператором відповідності числовим числом, наприклад, замінити лише 2-е входження:
$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/2; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC foo DEF bar GHI <foo KLM bar> NOP foo QRS bar TUV