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

<p>мне нужно было найти все файлы, которые содержали определенный шаблон строки. первое решение, которое приходит на ум, это использование<em> find </em>piped с<em> xargs grep </em>:</p><pre><code>find . -iname '*.py' | xargs grep -e 'your\_pattern' </code></pre><p>но если мне нужно найти шаблоны, которые занимают более одной строки, я застрял, потому что ванильный grep не может найти многострочные шаблоны.</p>

<p>поэтому я обнаружил <a href="http://www.pcre.org/"><strong><em>pcregrep</em></strong></a> , что означает <strong>perl-совместимые регулярные выражения grep</strong>.</p><p>например, вам нужно найти файлы, в которых сразу за переменной «<em>\_name</em>» следует переменная «<em>\_description</em>»:</p><pre><code>find . -iname '*.py' | xargs pcregrep -m '\_name.*\n.*\_description' </code></pre><p>совет: вам нужно включить символ разрыва строки в ваш шаблон. в зависимости от вашей платформы это может быть '\ n',\r ','\r\n ', ...</p>

<p>почему бы вам не пойти на <a href="http://www.gnu.org/software/gawk/manual/gawk.html">awk</a> :</p><pre><code>awk '/start pattern/,/end pattern/' filename </code></pre>

<p>вот пример использования <a href="https://www.gnu.org/software/grep/">gnu <code>grep</code></a> :</p><pre><code>grep -pzo '\_name.*\n.*\_description' </code></pre><blockquote> <p><code>-z</code>/<code>--null-data</code> обрабатывать входные и выходные данные как последовательности строк.</p> </blockquote><p>смотрите также <a href="https://stackoverflow.com/questions/3717772/regex-grep-for-multi-line-search-needed/7167115#7167115">здесь</a> </p>

<p><code>grep -p</code> также использует libpcre, но <em>намного</em> более широко установлен. чтобы найти полный раздел <code>title</code> html-документа, даже если он занимает несколько строк, вы можете использовать это:</p><pre><code>grep -p '(?s)<title>.*</title>' example.html </code></pre><p>поскольку <a href="http://www.pcre.org/">проект pcre</a> реализует стандарт perl, используйте документацию perl для справки:</p><ul> <li> <a href="http://perldoc.perl.org/perlre.html#modifiers">http://perldoc.perl.org/perlre.html#modifiers</a> </li> <li> <a href="http://perldoc.perl.org/perlre.html#extended-patterns">http://perldoc.perl.org/perlre.html#extended-patterns</a> </li> </ul>

<p>вот более полезный пример:</p><pre><code>pcregrep -mi "<title>(.*\n){0,5}</title>" afile.html </code></pre><p>он ищет тег заголовка в html-файле, даже если он занимает до 5 строк.</p><p>вот пример неограниченного количества строк:</p><pre><code>pcregrep -mi "(?s)<title>.*</title>" example.html </code></pre>

<p>с <a href="https://github.com/ggreer/the\_silver\_searcher">серебряный искатель</a> :</p><pre><code>ag 'abc.*(\n|.)*efg' </code></pre><p>оптимизация скорости поисковика серебра могла бы здесь проявиться.</p>

<p>вы можете использовать альтернативу grep <a href="http://sift-tool.org">sift</a> здесь (отказ от ответственности: я автор).</p><p>он поддерживает многострочное сопоставление и ограничивает поиск конкретными типами файлов из коробки:</p><pre>sift -m --files '* .py' 'your\_pattern'</pre><p>(поиск по всем * .py файлам по указанному шаблону регулярных регулярных выражений)</p><p>он доступен для всех основных операционных систем. посмотрите на страницу <a href="http://sift-tool.org/samples.html">samples</a> , чтобы узнать, как ее можно использовать для извлечения многострочных значений из файла xml.</p>

<p>этот ответ может быть полезен:</p><p> <a href="https://stackoverflow.com/questions/3717772/regex-grep-for-multi-line-search-needed/7167115#7167115">требуется регулярное выражение (grep) для многострочного поиска</a> </p><p>для рекурсивного поиска вы можете использовать флаги -r (рекурсивный) и --include (шаблон glob). увидеть:</p><p> <a href="https://stackoverflow.com/questions/221921/grep-exclude-include-syntax-do-not-grep-through-certain-files/221929#221929">использовать grep --exclude/- включить синтаксис, чтобы не просматривать определенные файлы</a> </p>

<pre><code>perl -ne 'print if (/begin pattern/../end pattern/)' filename </code></pre>

<p>использование редактора <code>ex</code> <a href="http://wiki.bash-hackers.org/internals/shell\_options#globstar"><code>vi</code> и опции \_/globstar</a> (синтаксис аналогичен <code>awk</code> и <code>sed</code>):</p><pre><code>ex +"/string1/,/string3/p" -r -scq! file.txt </code></pre><p>где <code>aaa</code> - ваша начальная точка, а <code>bbb</code> - ваш конечный текст.</p><p>чтобы выполнить рекурсивный поиск, попробуйте:</p><pre><code>ex +"/aaa/,/bbb/p" -scq! **/*.py </code></pre><p><sup>примечание. чтобы включить синтаксис <code>**</code>, запустите <code>shopt -s globstar</code> (bash 4 или zsh).</sup></p>

<p>@marcin: awk пример не жадный:</p><pre><code>awk '{if ($0 ~ /start pattern/) {triggered=1;}if (triggered) {print; if ($0 ~ /end pattern/) { exit;}}}' filename </code></pre>