Как я могу найти многострочный шаблон в файле? - PullRequest
107 голосов
/ 30 сентября 2008

Мне нужно было найти все файлы, которые содержали определенный строковый шаблон. Первое решение, которое приходит на ум, - это использование find по трубопроводу с xargs grep :

find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'

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

Ответы [ 11 ]

92 голосов
/ 30 сентября 2008

Итак, я обнаружил pcregrep , что означает Регулярные выражения, совместимые с Perl GREP .

Например, вам нужно найти файлы, в которых сразу за переменной ' _name ' следует переменная ' _description ':

find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'

Совет: вам нужно включить символ разрыва строки в ваш шаблон. В зависимости от вашей платформы это может быть '\ n', \ r ',' \ r \ n ', ...

84 голосов
/ 15 сентября 2010

Почему бы вам не пойти на awk :

awk '/Start pattern/,/End pattern/' filename
67 голосов
/ 30 сентября 2008

Вот пример использования GNU grep:

grep -Pzo '_name.*\n.*_description'

-z / --null-data Обрабатывать входные и выходные данные как последовательности строк.

Смотри также здесь

20 голосов
/ 26 июля 2012

grep -P также использует libpcre, но намного более широко установлен. Чтобы найти полный title раздел HTML-документа, даже если он занимает несколько строк, вы можете использовать это:

grep -P '(?s)<title>.*</title>' example.html

Поскольку проект PCRE соответствует стандарту perl, для справки используйте документацию perl:

15 голосов
/ 30 сентября 2008

Вот более полезный пример:

pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html

Он ищет тег заголовка в html-файле, даже если он занимает до 5 строк.

Вот пример неограниченного количества строк:

pcregrep -Mi "(?s)<title>.*</title>" example.html 
7 голосов
/ 14 января 2015

С серебряным искателем :

ag 'abc.*(\n|.)*efg'

Оптимизация скорости поисковика серебра могла бы проявиться здесь.

4 голосов
/ 23 февраля 2015

Вы можете использовать альтернативу grep просеивать здесь (отказ от ответственности: я автор).

Он поддерживает многострочное сопоставление и ограничивает поиск определенными типами файлов из коробки:

sift -m --files '*.py' 'YOUR_PATTERN'

(поиск по всем * .py файлам по указанному шаблону регулярных регулярных выражений)

Доступно для всех основных операционных систем. Взгляните на образец страницы , чтобы увидеть, как ее можно использовать для извлечения многострочных значений из файла XML.

3 голосов
/ 24 августа 2011

Этот ответ может быть полезен:

Требуется регулярное выражение (grep) для многострочного поиска

Для рекурсивного поиска вы можете использовать флаги -R (рекурсивный) и --include (шаблон GLOB). См:

Используйте синтаксис grep --exclude / - include, чтобы не просматривать определенные файлы

2 голосов
/ 04 апреля 2016
perl -ne 'print if (/begin pattern/../end pattern/)' filename
1 голос
/ 17 октября 2015

Использование ex / vi редактора и опция globstar (синтаксис аналогичен awk и sed):

ex +"/string1/,/string3/p" -R -scq! file.txt

, где aaa - ваша начальная точка, а bbb - ваш конечный текст.

Чтобы выполнить рекурсивный поиск, попробуйте:

ex +"/aaa/,/bbb/p" -scq! **/*.py

Примечание. Чтобы включить синтаксис **, запустите shopt -s globstar (Bash 4 или zsh).

...