Рецепт sed: как делать вещи между двумя шаблонами, которые могут быть либо на одной строке, либо на двух линиях?

Допустим, мы хотим сделать некоторые замены только между некоторыми шаблонами, пусть они будут<a> а также</a> для ясности... (all right, all right, they're start and end!.. Jeez!)

Так что я знаю, что делать, еслиstart а такжеend всегда встречаются в одной строке: просто создайте правильное регулярное выражение.

Я также знаю, что делать, если они гарантированно находятся в разных строках, и меня не волнует что-либо в строке, содержащейend и я также в порядке с применением всех команд в строке, содержащейstart before start: просто укажите диапазон адресов как/start/,/end/.

Это, однако, не очень полезно. Что делать, если мне нужно сделать более умную работу, например, внести изменения внутри{...} блок?

Одна вещь, о которой я могу думать, это сломать{ а также} перед обработкой и последующим соединением:

sed 's/{\|}/\n/g' input | sed 'main stuff' | sed ':a $!{N;ba}; s/\n\(}\|{\)\n/\1/g'

Другой вариант противоположен:

cat input | tr '\n' '#' | sed 'whatever; s/#/\n/g'

Оба они ужасны, главным образом потому, что операции не ограничены одной командой. Второй вариант еще хуже, потому что нужно использовать какой-то символ или подстроку в качестве «нового символа». при условии, что он не присутствует в исходном тексте.

Таким образом, вопрос: есть ли лучшие способы или можно оптимизировать вышеупомянутые? Это довольно обычное задание из того, что я прочитал в недавних SO-вопросах, поэтому я хотел бы выбрать наилучшую практику раз и навсегда.

Постскриптум Я в основном заинтересован в чистомsed решения: может ли работа быть сделана с одним вызовомsed и ничего больше? Пожалуйста, нетawk, Perlи т. д .: это скорее теоретический вопрос, а не "нужно сделать работу как можно скорее" один.

Ответы на вопрос(1)

Ваш ответ на вопрос