Це як надійно виконати не жадібну відповідність багато символьних рядків за допомогою 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