Sed range и удаление последней подходящей строки - PullRequest
0 голосов
/ 07 июня 2018

У меня есть эти данные:

One
  two
  three
Four
  five
  six
Seven
  eight

И эта команда:

sed -n '/^Four$/,/^[^[:blank:]]/p'

Я получаю следующий вывод:

Four
  five
  six
Seven

Как я могу изменить этоВыражение sed не соответствует последней строке вывода?Таким образом, идеальный вывод должен быть:

Four
  five
  six

Я пробовал много вещей, включая восклицательные знаки, но не смог подобраться к этому.

Ответы [ 6 ]

0 голосов
/ 08 июня 2018

Это может сработать для вас (GNU sed):

sed '/^Four/{:a;n;/^\s/ba};d' file

Если строка начинается с Four, напечатайте ее и любые последующие строки, начинающиеся с пробела.

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

sed '/^\S/h;G;/^Four/MP;d' file

Если строка начинается с не пробела, скопируйте ее в область удержания (HS).Добавьте HS к каждой строке, и если любая из них начинается с Four, выведите первую строку и удалите оставшуюся.Это удалит все строки, кроме раздела, начинающегося с Four.

0 голосов
/ 08 июня 2018
grep -Pzo '\n\KFour\n(\s.+\n)+' input.txt

Выход

Four
  five
  six
0 голосов
/ 08 июня 2018

Вы используете не тот инструмент.sed для s / old / new, вот и все.Просто используйте awk:

$ awk '/^[^[:blank:]]/{f=/^Four$/} f' file
Four
  five
  six

Как это работает: Каждый раз, когда он находит строку, которая не начинается с пробелов (/^[^[:blank:]]/), он устанавливает флаг f (для «найден») в 1если эта строка начинается с Four и 0 в противном случае (f=/^Four$/).Всякий раз, когда f отличен от нуля, это интерпретируется как истинное условие и, таким образом, вызывает поведение awks по умолчанию, которое заключается в печати текущей строки.Поэтому, когда он попадает в блок, начинающийся с Four, он печатает каждую строку в этом блоке, потому что f равен 1 / true, а для всех остальных блоков он не печатается, поскольку f равен 0 / false.

0 голосов
/ 07 июня 2018

Используйте цикл "do.. while ()":

sed -n '/^Four$/{:a;p;n;/^[[:blank:]]/ba}'

детали:

/^Four$/ {
    :a         # define the label "a"
    p          # print the pattern-space
    n          # load the next line in the pattern space
    /^[[:blank:]]/ba # if the pattern succeeds, go to label "a"
}
0 голосов
/ 07 июня 2018

Вы можете перейти на другой sed и пропустить последнюю строку:

sed -n '/^Four$/,/^[^[:blank:]]/p' file | sed '$d'

Four
  five
  six

В качестве альтернативы вы можете использовать:

sed -n '/^Four$/,/^[^[:blank:]]/{/^Four$/p; /^[^[:blank:]]/!p;}' file
0 голосов
/ 07 июня 2018

После awk может вам помочь.

awk '!/^ /{flag=""} /Four/{flag=1} flag'   Input_file

Вывод будет следующим:

Four
  five
  six

Также в случае необходимости сохранить вывод в сам файл Input_file добавьте> temp_file && mv temp_file Input_file к вышеуказанному коду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...