BASH: если строка соответствует - удалить строку + следующие 33 строки - PullRequest
2 голосов
/ 06 января 2012

У меня есть файл, полный записей ... каждая запись имеет длину 34 строки.

Мне нужно удалить этот файл из любой записи, где первая строка записи соответствует строке. Эта первая строка является кодом местоположения. Файл должен быть очищен от всех записей из определенного места. Есть пустая строка после первой строки в каждой записи ... фактически несколько, однако любое появление пустой строки будет указывать, что эта запись принадлежит этому местоположению.

Итак -

если строка соответствует а следующая строка пуста затем удалите строку + 33 строки после строки.

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

Некоторые просили образец (эта запись состоит из 34 строк в реальной жизни):

LOCATION



DARRYL MITHRANDIR
5 LONGBOTTOM LEAF LN
HOBBITON, ME  99999

We rang to notify you that we have the following items:

1 blade - glamdring = $1,000
1 shrunken troll head = $1

Available for pick-up at the following location:

LOCATION
8 SMAUG LN
MORDOR, ME  99998

Как вы можете видеть, местоположение всегда происходит как первая строка в записи, за которой следует серия пустых строк. Это происходит в другом месте записи, но всегда сопровождается строкой текста, указывающей адрес улицы.

Ответы [ 3 ]

4 голосов
/ 06 января 2012

Ну, вот ответ с awk.Измените LOCATION на любое регулярное выражение, соответствующее вашим потребностям.

  awk '/LOCATION/{l=$0;getline;if(!$0)i=33; else print l}i{if(--i);next}1'

Пример, основанный на вашем

$ cat ./input
LOCATION  ### DELETE THIS RECORD ###



DARRYL MITHRANDIR
5 LONGBOTTOM LEAF LN
HOBBITON, ME  99999

We rang to notify you that we have the following items:

1 blade - glamdring = $1,000
1 shrunken troll head = $1

Available for pick-up at the following location:

CHUCKS AMAZING BARGAINS
8 SMAUG LN
MORDOR, ME  99998
LOCATION  ### DONT DELETE THIS RECORD, NEXT LINE NOT BLANK ###
FOO BAR
31337 EXAMPLE WAY
EXAMPLETON, EX  12345

We rang to notify you that we have the following items:

1 ring of awkfu = $99,000,000
1 troll face = jelly?

Available for pick-up at the following location:

SIEGEXS AMAZING EXAMPLES
314159 PI CIRCLE
NOWHERE, NA 00000

Вывод с примером из 17 строк / записей

$ awk '/LOCATION/{l=$0;getline;if(!$0)i=17; else print l}i{if(--i);next}1' ./input
LOCATION  ### DONT DELETE THIS RECORD, NEXT LINE NOT BLANK ###
FOO BAR
31337 EXAMPLE WAY
EXAMPLETON, EX  12345

We rang to notify you that we have the following items:

1 ring of awkfu = $99,000,000
1 troll face = jelly?

Available for pick-up at the following location:

SIEGEXS AMAZING EXAMPLES
314159 PI CIRCLE
NOWHERE, NA 00000
2 голосов
/ 06 января 2012

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

sed -i '/LOCATION/{N;/\n$/{:a;N;x;s/^/X/;/^X\{32\}/{g;d};x;ba}}' file

Согласно инструкциям:

, если строка соответствует, а следующая строка пуста, затем удалить строку + 33 строки после строки.

Объяснение:

  • (1) Соответствует LOCATION
  • Если (1) выше
    • добавить следующую строку N
    • (2) Совпадение последнего символа пространства образца (PS) с новой строкой, т.е. пустой строкой.
      • если (2) выше
        • создать метку :a
        • , добавить новую строку, а затем следующую строку (PS) N
        • поменяйте местами PS с пробелом (другой регистр HS) x
        • и добавьте X к передней части HS s/^/X/
        • (3) Сопоставьте HS с 32 X /^X\{32\}/
          • Если (3) выше
            • скопировать PS через HS g
            • удалить HS и начать следующий цикл d
          • остальное
            • переключение с HS обратно на PS x
            • Перейти к метке ba
1 голос
/ 06 января 2012

Вы можете сделать что-то вроде этого с помощью awk -

awk '/YOUR PATTERN/ {
i=$0;getline; if($0~/^$/)
for(i=1;i<34;i++) {getline} else {print i,$0;next}}1' file

Объяснение:

  1. Мы ищем строки, содержащие ваш шаблон.
  2. Еслимы находим его, храним всю строку в переменной i.
  3. Затем мы проверяем следующую строку с помощью ключевого слова getline, если это blank line, мы спускаемся вниз 33 раза.
  4. Если следующая строка не является пустой строкой, мы печатаем переменную i.
  5. 1 в самом конце предназначена для печати всех строк, которые не соответствуют шаблону.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...