SED: удалить X строк после матча - PullRequest
1 голос
/ 10 мая 2019

Я пытаюсь удалить диапазон, используя sed. Диапазон от известного совпадения и следующих 2 строк. Допустим, я хочу удалить все строки, которые начинаются с Don't, а затем 2 строки, которые следуют.

Обратите внимание, что я также делаю замены в командном файле sed. Поэтому я избегаю использования -n и /p в моем пространстве решений.

По какой-то причине я хочу ограничиться одним вызовом sed.

Вот мои данные (data.txt):

Print Me
Please Output This line
Don't Print Me and 2 more lines
This line is no good
So is this one
We should see this line
And this one, too.

Вот мой ожидаемый результат:

Print Me
Please Output This line
We should see this line
And this one, too.

Вот попытка пойти на это:

sed -f delete_dont_plus_2.sed data.txt

С этим как delete_dont_plus_2.sed:

/^Don't/,+2d

Вот мой результат:

sed: 1: delete_dont_plus_2.sed: expected context address

Я также пробовал это:

/^Don't/,/^Don't/+2d
/^Don't/,{/^Don't/+2}d

Второй подход к этому вопросу:

Допустим, мы хотели сделать этот код немного более надежным. Сегодня есть еще 2 строки, которые необходимо удалить, но кто знает, сколько строк будет в будущем. Допустим, мы хотим удалить до, но не включая We should see this line. В этом варианте вопроса результаты точно такие же. Опять же, давайте рассмотрим ограниченный BSD sed, поэтому мы не можем использовать выражение вроде /^Don't/,/^We should see this line/-1d.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 10 мая 2019

Возможно, вы используете sed, который не поддерживает адреса в форме regexp,+n.Вот обходной путь для этого конкретного случая:

/^Don't/{N;N;d;}

Он просто считывает еще две строки в пространство образца, когда найден ^Don't, и удаляет их вообще.

Но в любом случае, я думаюСед не подходит для этого, вы должны использовать .Например:

awk '/^Don\047t/{c=2;next} !(c&&c--)' file

cf: Печать с помощью sed или awk строки, следующей за соответствующим шаблоном


по

Давайтескажем, мы хотим удалить до, но не включая We should see this line.В этом варианте вопроса результаты абсолютно одинаковы.

Используя sed, вам нужно написать один и тот же RE дважды:

/^Don't/,/^We should see this line/{/^We should see this line/!d;}

Используя awk, вы не делаетедаже нужны RE:

awk 'index($0,"Don\047t")==1{d=1} $0=="We should see this line"{d=0} !d' file
1 голос
/ 10 мая 2019

С GNU sed:

sed "/^Don't/,+2d" file

Выход:

Print Me
Please Output This line
We should see this line
And this one, too.
0 голосов
/ 12 мая 2019

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

sed '/^Don'\''t/{s/.*/X/;h;d};x;/X/!{x;b};s/^/X/;/^XXX/z;x;d' file

Это решение ведет подсчет времени, с которым встречается регулярное выражение.

NB Если одна из двух строк, следующих заregexp также является регулярным выражением, счетчик перезапускается.

Решение менее специфичное и программируемое для GNU:

sed '/^Don'\''t/{s/.*/X/;h;d};x;/X/!{x;b};s/^/X/;/^XX\{2\}/s/.*//;x;d' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...