LINUX.ORG.RU

grep с регулярным выражением в несколько строк


0

0

Помогите, пожалуйста. Нужно найти все текстовые файлы, содержащие в трёх последовательных строках определённые ключевые слова. Например, так:

_chemical_formula.........
;
......Fe.........

То есть в строках, идущих друг за другом, должны содержаться слова '_chemical_formula' ';' и 'Fe' . Часть файлов -- с концами строк DOS/Windows, часть -- Unix.

Можно ли в grep описать регулярным выражением несколько строк? Или чем заменить grep?

★★★★

Ответ на: комментарий от anonymous

Спасибо, работает. Правда, надо было .* добавить: 

#!/bin/sh

isok=$(sed -n 's/\r//
/^_chemical_formula.*$/!b
n
/^;.*$/!b
n
/^.*Fe.*$/!b
p
q' "$1")

[ -n "$isok" ] && echo "$1"


Только, как выяснилось, я с форматом напутал. Между ';' и 'Fe' может 
быть до десятка строк, заранее неизвестно сколько, а потом снова 
строка, начинающаяся на ';' . 

_chemical_formula.........
;
...............
......Fe......... 
.............
;


Что тут можно сделать, помимо написания нескольких скриптов, каждый под своё число строк?

acheron ★★★★
() автор топика

В итоге прогоняю каждый файл через tr '\n\r' '$$' и grep-ом ищу в содержимом. Задачу решил, но вопрос остался :)

acheron ★★★★
() автор топика
Ответ на: комментарий от acheron

Я бы так написал (не проверял).

awk ' /_chemical_formula/ {f=1}
      /;/  && f==2        {f=0}
      /;/  && f==1        {f=2}
      /Fe/ && f==2        {print "Found at line:", NR, " in file:" ,FILENAME}
    ' /dir/files*.txt

sdio ★★★★★
()

Сам выяснил, благодаря подсказке с forums.gentoo.org. Если включить --perl-regexp и явно указывать каждый конец строки \n можно растянуть выражение на несколько строк. В моём случае же число строк текста между ';', 'Fe' и другой ';' произвольно (но меньше, скажем, 10). Можно обозначать такие строки '.*\n*'.

При большом числе '.*\n*' (4 для файла ~8М) grep говорит "Аварийный останов". Никто не подскажет, как правильно описать это в багрепорте?

acheron ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.