Используйте sed, чтобы удалить строку, и ту, что ниже, если она содержит 1 шаблон, но не другой - PullRequest
0 голосов
/ 13 мая 2018

Нашел пару примеров, похожих на то, что я хочу, но они не работают для меня или других, судя по комментариям.

Я хочу, чтобы это

#Hello my name is Chris
next line of random txt
#Hello my name is Bob
next line of random txt
Hello Ana is my name #
next line of random txt
Another Line

было таким

#Hello my name is Chris
next line of random txt
Hello Ana is my name #
next line of random txt
Another Line

Строки, содержащие "#", но не "Крис" или "Ана", удаляются вместе со строкой под ними.

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

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

sed '/Chris\|Ana/b;/#/!b;$!N;d' file

Если строка содержит разрыв * Chris или Ana, т. Е. Не обрабатывать дальше и печатать как обычно.Аналогично, если строка не содержит #.Если текущая строка не последняя, ​​возьмите следующую и удалите обе.В противном случае, если это последняя строка, удалите ее тоже.

0 голосов
/ 13 мая 2018

С учетом ввода:

#Hello my name is Chris
next line of random txt 1
#Hello my name is Bob
next line of random txt 2
Hello Ana is my name #
next line of random txt 3
Another Line

Либо скрипт:

sed -e '/#/ { /Chris/b' -e '/Ana/b' -e 'N; d; }' data

или сценарий:

sed -E \
    -e '/#/ {
                 /(Chris|Ana)/b
                 N
                 d
            }' \
    data

генерирует:

#Hello my name is Chris
next line of random txt 1
Hello Ana is my name #
next line of random txt 3
Another Line

Кажется, это соответствует вашей спецификации. Первый даже не использует синтаксис расширенного регулярного выражения (ERE), поэтому он максимально переносим, ​​но второй показывает, что его можно легко изменить для использования синтаксиса ERE. В BSD sed после команды ветвления (b) нельзя ставить точку с запятой; то, что следует, должно идти в другой строке или в другом аргументе -e. b без явной метки означает «переход к концу сценария».

...