it-swarm.com.ru

Как мне найти многострочный шаблон в файле?

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

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

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

104
Oli

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

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

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

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

92
Oli

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

awk '/Start pattern/,/End pattern/' filename
81
Amit

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

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

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

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

65
ayaz

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

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

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

20
bukzor

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

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

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

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

pcregrep -Mi "(?s)<title>.*</title>" example.html 
14
Oli

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

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

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

7
Shwaydogg

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

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

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

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

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

4
svent

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

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

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

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

3
albfan
Perl -ne 'print if (/begin pattern/../end pattern/)' filename
2
pbal

Использование редактора exvi и опции _/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).

1
kenorb

@Marcin: Awk пример не жадный:

awk '{if ($0 ~ /Start pattern/) {triggered=1;}if (triggered) {print; if ($0 ~ /End pattern/) { exit;}}}' filename
0
Martin