Подтвердить что ты не робот

Исключая первую и последнюю строки из sed/START/,/END/

Рассмотрим вход:

=sec1=
some-line
some-other-line

foo
bar=baz

=sec2=
c=baz

Если я хочу обработать только = sec1 =, я могу, например, закомментировать раздел:

sed -e '/=sec1=/,/=[a-z]*=/s:^:#:' < input

... ну, почти.

Это будет прокомментировать строки, включая строки "= sec1 =" и "= sec2 =", и результат будет примерно таким:

#=sec1=
#some-line
#some-other-line
#
#foo
#bar=baz
#
#=sec2=
c=baz

Мой вопрос: Самый простой способ исключить начальную и конечную строки из /START/,/END/range в sed?

Я знаю, что для многих случаев уточнение "s:" когтей может дать решение в этом конкретном случае, но я следую за общим решением здесь.

В " Sed - введение и учебник" Брюс Барнетт пишет: "Я покажу вам, как ограничить команду до, но не включая строку, содержащую указанный шаблон.", но я не смог найти, где он на самом деле показывает это.

В ПОЛЕЗНЫЕ ОДНОГРАНИЧНЫЕ СЦЕНАРИИ ДЛЯ СЕПА" Составив Эрика Пемца, я мог бы найти только инклюзивный пример:

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p'             # case sensitive
4b9b3361

Ответ 1

Это должно сделать трюк:

sed -e '/=sec1=/,/=sec2=/ { /=sec1=/b; /=sec2=/b; s/^/#/ }' < input

Это совпадение между sec1 и sec2 включительно, а затем просто пропускает первую и последнюю строку с помощью команды b. Это оставляет желаемые строки между sec1 и sec2 (exclusive), а команда s добавляет знак комментария.

К сожалению, вам нужно повторить регулярные выражения для соответствия разделителей. Насколько я знаю, нет лучшего способа сделать это. По крайней мере, вы можете держать регулярные выражения чистыми, даже если они используются дважды.

Это адаптировано из Часто задаваемые вопросы SED: как мне адресовать все строки между RE1 и RE2, за исключением самих строк?

Ответ 2

Если вас не интересуют строки за пределами диапазона, но просто хотите, чтобы не включительный вариант примера из Айовы/Монтаны из вопроса (что и привело меня сюда), вы можете написать "за исключением первый и последний совпадающие строки" достаточно легко со вторым sed:

sed -n '/PATTERN1/,/PATTERN2/p' < input | sed '1d;$d'

Лично я нахожу это немного яснее (хотя и медленнее на больших файлах), чем эквивалент

sed -n '1,/PATTERN1/d;/PATTERN2/q;p' < input

Ответ 3

Другой способ:

sed '/begin/,/end/ {
       /begin/n
       /end/ !p
     }'

/begin/n → пропустить строку, которая имеет шаблон "начать"
/end/ !p → распечатать все строки, которые не имеют шаблона "end"

Взято из учебника Bruce Barnett sed http://www.grymoire.com/Unix/Sed.html#toc-uh-35a

Ответ 4

вы также можете использовать awk

awk '/sec1/{f=1;print;next}f && !/sec2/{ $0="#"$0}/sec2/{f=0}1' file

Ответ 5

Я использовал:

sed '/begin/,/end/{/begin\|end/!p}'

Это приведет к поиску всех строк между шаблонами, затем распечатает все, что не содержит шаблонов