Извлечь подстроки между строками

У меня есть файл с таким текстом:

      ###interest1 moreinterest1### sometext ###interest2###
not-interesting-line
sometext ###interest3###
sometext ###interest4### sometext othertext ###interest5### sometext ###interest6###

Я хочу извлечь все строки между ### .

Мой желаемый результат будет примерно таким:

      interest1 moreinterest1
interest2
interest3
interest4
interest5
interest6

Я пробовал следующее:

      grep '###' file.txt | sed -e 's/.*###\(.*\)###.*/\1/g'

Это почти работает, но, похоже, захватывает только первый экземпляр в строке, поэтому первая строка в моем выводе захватывает только

      interest1 moreinterest1

скорее, чем

      interest1 moreinterest1
interest2

5 ответов

Решение

Вот сингл awk команда для достижения этого, которая создает разделитель полей и печатает каждое четное поле:

      awk -F '###' '{for (i=2; i<NF; i+=2) print $i}' file

interest1 moreinterest1
interest2
interest3
interest4
interest5
interest6

Вот альтернатива grep + sed решение:

      grep -oE '###[^#]*###' file | sed -E 's/^###|###$//g'

Предполагается, что нет # персонажи между ### маркеры.

С GNU awk для многосимвольного RS:

      $ awk -v RS='###' '!(NR%2)' file
interest1 moreinterest1
interest2
interest3
interest4
interest5
interest6

Ты можешь использовать pcregrep:

      pcregrep -o1 '###(.*?)###' file

Регулярное выражение - ###(.*?)### - сопоставляет, затем захватывает в Группу 1 любые ноль или больше символов, кроме символов разрыва строки, как можно меньше, а затем сопоставляет ###.

o1 опция выводит только значение группы 1.

См. Демонстрацию регулярных выражений в Интернете.

      sed 't x
s/###/\
/;D; :x
s//\
/;t y
D;:y
P;D' file

Заменив "###" на новую строку, D, затем условно переходя к P если вторая замена "###" успешна.

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

      sed -n 's/###/\n/g;/[^\n]*\n/{s///;P;D}' file

Заменить все вхождения по новой строке.

Если строка содержит новую строку, удалите все символы перед первой новой строкой включительно, распечатайте детали до следующей новой строки включительно, удалите эти детали и повторите.

Другие вопросы по тегам