Sed multiline заменить

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

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

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

asdas

this should be there

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

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

sed -n '1ч;! 1 Н; ${; г; s///< <] * TAG → > //г; р;}' < test.txt

Но некоторые из них не дали правильного вывода. Второй тег, содержащий символ " > ", не удался в регулярном выражении. Не знаете, где я ошибаюсь?

Любая идея, как это сделать?

Ответы

Ответ 1

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

sed '/\/\/<<<TAG/,/\/\/TAG>>>/d'

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

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

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

sed '@^//<<<@,@^//.*>>>@d'

Ответ 2

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

perl -ne 'print if !( [email protected]//<<<[email protected] .. [email protected]//TAG>>>@ )'
awk '/\/\/<<<TAG/,/\/\/TAG>>>/ {next} 1'

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

perl -ne 'print if !( [email protected]^//<<<(.*)@ .. [email protected]^//$1>>>[email protected] )'

Ответ 3

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

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

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

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