Удалить все между указанными символами, включая многострочные - PullRequest
0 голосов
/ 22 ноября 2018

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

## this must go ##
## also
 this
 must go
##
hello world
##and this one
too##

Я хочу удалить все между ## , включая несколько строк, поэтому у меня осталось только hello world

При этом удаляется только та часть, которая находится в одной строке:

sed -i.bak 's/##.*##//g' myfile

Как удалить и многострочный материал?

PS Я на MAC

Ответы [ 4 ]

0 голосов
/ 23 ноября 2018

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

sed -z 's/##[^#]*\(#[^#][^#]*\)*##\n\?//g' file

Опция -z позволяет всему файлу быть скопированным в пространство шаблона sed.Регулярное выражение состоит из трех частей.Первая часть соответствует ##, за которым следует ноль или более не #.Вторая часть соответствует нулю или более группе символов, состоящей из одного #, за которым следует не #, за которым следует ноль или более не #.Третья часть соответствует ## и возможному переводу строки.Это регулярное выражение удаляет такие совпадения глобально по всему файлу.

Это можно немного сократить, используя опцию -r, чтобы подсластить окончательное предложение:

sed -rz 's/##[^#]*(#[^#]+)*##\n?//g' file

Если версия sed делаетне предлагать ни один из вариантов, тогда другое решение:

sed 'H;$!d;x;s/.//;s/##[^#]*\(#[^#][^#]*\)*##\n\?//g' file

Следует отметить, что в приведенном выше примере все ## начинаются или заканчиваются в начале или конце строки и т. д.приведенное ниже решение также может соответствовать требованиям:

sed 's/^##/,/##$/d' file 
0 голосов
/ 22 ноября 2018

Дайте попытку этому:

sed -n '/^##/ { :1 ; /##$/ { d } ; n ; b 1 } ; p' myfile

Мудрецы прочитают этот превосходный урок: Sed - Введение и учебник Брюса Барнетта

Тест:

sed -n '/^##/ { :1 ; /##$/ { d } ; n ; b 1 } ; p' myfile

hello world
0 голосов
/ 22 ноября 2018

Вы можете использовать perl для достижения желаемого:

perl -0pe 's/##.*?##\R*//gs' file > newfile

См. онлайн-демонстрацию

Аргумент 0 позволяет найтисовпадения по всем линиям.

Шаблон соответствует

  • ## - два # символа
  • .*? - любые символы 0+ (четные символы разрыва строки из-за s модификатор) как можно меньше
  • ## - два # символа
  • \R* - любые 0+ последовательностей разрыва строки.
0 голосов
/ 22 ноября 2018

Это должно быть очень легкое задание для awk (если вы согласны с этим).Не могли бы вы попробовать, пожалуйста, добавьте объяснение в ближайшее время.

awk '/^##.*##$/{next} /^##$/{flag="";next} /^##/ && !/##$/{flag=1} flag{next} 1' Input_file

Добавление решения формы не одним вкладышем тоже сейчас.

awk '
/^##.*##$/{
  next
}
/^##$/{
  flag=""
  next
}
/^##/ && !/##$/{
  flag=1
}
flag{
  next
}
1
'   Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...