Диапазон адресов регулярного выражения sed минус (или плюс) количество строк

Всегда можно попробовать старый добрыйgrep:

grep -wFn 1.1.1.2 yourIPfile

или

ip=1.1.1.2 ; grep -wFn $ip yourIPfile

В обоих случаях вывод

1:node2,1.1.1.2
2
17.09.2019, 20:41
2 ответа

Вы были очень близки:

sed '/DESCRIPTION/p;//,/^[^ ]/!d;//d' filename

Будет делать то, что вы хотите. Почему?

  • Вы можете определить диапазон и удалить все, что находится за пределами этого диапазона, с помощью/start/,/stop/!d
  • Затем вы также хотите удалить последнюю строку совпадения. Следующий //dбудет делать так (пустой шаблон //соответствует последнему шаблону, таким образом, строка /stop/)
  • Но в вашем случае этот шаблон также соответствует первой строке. Неудача! Итак, давайте pнапечатаем его раньше, и вы снова получите команду, которую я показывал (, используя пустой шаблон)

Обновление с различными подходами

В своем комментарии вы назвали это «обходным путем», что с некоторой точки зрения так и есть. И вообще, для себя я выбрал бы другое,более sedподход:

sed '/^ /{H;d;};x;/^DESCRIPTION/!d' filename

Это должно казаться естественным для sedвлюбленных, но для некоторых может показаться странным на первый взгляд. Отсюда следует подход «желание -я -мог -помнить «-. Что это такое? Каждый раз, когда вы подходите к строке без отступа, вы думаете: «Хотел бы я помнить строки раньше, стоит ли их печатать». Затем мы просто предполагаем, что они есть в нашей памяти, в области хранения, поэтому мы можем просто xизменить пространство шаблонов и пространство хранения и dудалить их, если они не начинаются с DESCRIPTION(, если они начинаются с, он будет напечатан по умолчанию ).

Преимущество xзаключается в том, что каждая строка без отступа автоматически помещается в пространство для хранения, поэтому нам просто нужно добавить строки с отступом в пространство для хранения с помощью H. Часть /^ /{H;d;}делает (часть d, чтобы избежать вывода или дальнейшей обработки этих строк ).

Программист поступил бы наоборот. Они, вероятно, сделали бы вот такую ​​петлю:

sed '/DESCRIPTION/!d
  :loop
  N;/\n[^ ].*/!bloop
s///' filename

То есть отбрасываем все до тех пор, пока не встретим ключевое слово DESCRIPTION, затем запускаем цикл для сбора строк с Nи зацикливаем до тех пор, пока не появится строка с не -пробелом \n[^ ].*. В этом случае удалите последнюю строку (еще раз, воспользовавшись пустым шаблоном ).

Это тоже работает, но это не типичный способ работы в sed.

4
27.01.2020, 21:58

Да, sed поддерживает такие диапазоны адресов:

sed -n '/string1/,/string2/p file

В вашем случае попробуйте использовать опцию -Eдля расширенных регулярных выражений.

sed -nE '/this/,/^[^ ]/p' filename
0
27.01.2020, 21:58

Теги

Похожие вопросы