Рецепт 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
и т. д .: это скорее теоретический вопрос, а не "нужно сделать работу как можно скорее" один.