Sed Multiline заменить - PullRequest
       26

Sed Multiline заменить

15 голосов
/ 03 августа 2009

это мой пример текстового файла:

asdas
//<<<TAG
this should be removed
//TAG>>>
this should be there
//<<<TAG
T
>
asd
asd
//TAG>>>

для которого я хочу o / p как:

asdas

this should be there

Обычно я пытаюсь найти строки между "// << >>" (включая эти строки) и удалить их.

Я пытался использовать sed

сед-н '1h;! 1 H; $ {; г; s /// <<] * TAG >>> // г; р;}'

Но кое-как это не дало правильного вывода. Второй тег, который содержал символ «>», не прошел регулярное выражение. Не уверен, где я иду не так?

Есть идеи, как это сделать?

Ответы [ 3 ]

10 голосов
/ 03 августа 2009

Если вы пытаетесь удалить строки с буквенным текстом «TAG», попробуйте:

sed '/\/\/&#60;&#60;&#60;TAG/,/\/\/TAG&#62;&#62;&#62;/d'

Из ваших комментариев видно, что TAG может быть не буквальным, в этом случае:

sed '/^\/\/&#60;&#60;/,/^\/\/.*&#62;&#62;/d'

Это можно упростить, используя другой разделитель:

sed '@^//<<<@,@^//.*>>>@d'
3 голосов
/ 03 августа 2009

Вместо того, чтобы использовать решение sed, которое я дал, вам может понравиться любой из них в perl и awk:

perl -ne 'print if !( m@//&#60;&#60;&#60;TAG@ .. m@//TAG&#62;&#62;&#62;@ )'
awk '/\/\/&#60;&#60;&#60;TAG/,/\/\/TAG&#62;&#62;&#62;/ {next} 1'

Учитывая, что я думаю, что вы действительно не хотите, чтобы TAG был константой, самое чистое решение, о котором я знаю, это вариант perl:

perl -ne 'print if !( m@^//&#60;&#60;&#60;(.*)@ .. m@^//$1&#62;&#62;&#62;$@ )'
0 голосов
/ 08 марта 2013

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

sed '\|^//<<<|,\|^//.*>>>|d' file

Awk версия соответствует концу с тем же именем тега:

awk -F'//<<<|//|>>>' '$2{p=$2; while(getline && p!=$2); next}1' file
...