sed - удалить из pattern1 до pattern2 в pattern3 после pattern2 - PullRequest
1 голос
/ 09 июля 2019

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

Скажем, у меня есть ввод, подобный следующему, и я хочу удалить строки с 6 по 11, потому что шаблон notthis находится между шаблонами start и end:

start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
OgytsRhZbD8T
notthis
0PlcUh2RLvVW
tsz2S80SyW9p
end
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
end

Я изменил то, что, как я думал, понял, с этого ответа на что-то вроде этого, но это не работает:

/^start$/{$!{N;/^start\n(.*\n)*notthis.*\n(.*\n)*end/d;ty;P;D;:y}}

Это потому, что N только добавляет строку, следующую за начальным шаблоном ^start$, к пространству шаблона и игнорирует то, что следует? И как правильно достичь того, что я пытаюсь сделать?

Ответы [ 3 ]

3 голосов
/ 09 июля 2019

sed - для простых замен отдельных строк, - это все .Для всего остального, что вы должны использовать awk, например, с GNU awk для multi-char RS, этот краткий скрипт выдаст желаемый результат из введенного вами ввода:

$ awk 'BEGIN{RS=ORS="end\n"} !/notthis/' file
start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
end

или более четко, более надежно и прощедля улучшения с любым awk:

$ cat tst.awk
/start/ { f = 1 }
f {
    rec = rec $0 ORS
    if ( /end/ ) {
        if ( rec !~ /notthis/ ) {
            printf "%s", rec
        }
        rec = ""
        f = 0
    }
}
$
$ awk -f tst.awk file
start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
end

Вышеописанное будет работать эффективно и надежно при использовании любого awk в любой оболочке на каждом компьютере UNIX, его легко понять и легко изменить, если / когда ваши требования изменятся.

0 голосов
/ 10 июля 2019

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

sed '/^start/{:a;N;/end$/!ba;/notthis/d}' file

Соберите строки между start и end и, если они содержат строку notthis, удалите их.

0 голосов
/ 09 июля 2019

Вот еще один awk скрипт. Надеюсь, что соответствует частичное описание проблемы.

script.awk

BEGIN {omitMark = "notthis"}  # assign omit marker as ReqExp
/start/, /end/ {   # define RegExp range for omission section 
    if ($0 ~ omitMark) next;  # if matched omission marker skip processing
    print;  # print not ommited currnt line in section
    next;   # skip to process next line in section
}
1;  # print any line not in section.

input.txt

start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
OgytsRhZbD8T
notthis
0PlcUh2RLvVW
tsz2S80SyW9p
end
notthis
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
notthis
end
notthis

работает:

awk -f script.awk input.txt

выход:

start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
OgytsRhZbD8T
0PlcUh2RLvVW
tsz2S80SyW9p
end
notthis
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
end
notthis
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...