Как искать многострочный шаблон в файле?
Мне нужно было найти все файлы, содержащие определенный шаблон строки. Первое решение, которое приходит на ум, это использовать find pipeed с xargs grep:
find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'
Но если мне нужно найти шаблоны, которые охватывают более одной строки, я застрял, потому что ванильный grep не может найти многострочные шаблоны.
Ответы
Ответ 1
Итак, я обнаружил pcregrep, что означает Perl Compatible Regular Expressions GREP.
Например, вам нужно найти файлы, где переменная "_name" сразу же следует переменной "_description":
find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'
Совет. Вам нужно включить символ разрыва строки в свой шаблон. В зависимости от вашей платформы это могут быть "\n", "r", "\ r\n",...
Ответ 2
Почему бы вам не пойти на awk:
awk '/Start pattern/,/End pattern/' filename
Ответ 3
Вот пример использования GNU grep
:
grep -Pzo '_name.*\n.*_description'
-z
/--null-data
Обрабатывать входные и выходные данные как последовательности строк.
Смотрите также здесь
Ответ 4
grep -P
также использует libpcre, но гораздо более широко установлен. Чтобы найти полный раздел title
html-документа, даже если он охватывает несколько строк, вы можете использовать это:
grep -P '(?s)<title>.*</title>' example.html
Поскольку проект PCRE реализует стандарт perl, используйте документацию perl для справки:
Ответ 5
Вот более полезный пример:
pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html
Он ищет тег заголовка в html файле, даже если он охватывает до 5 строк.
Вот пример неограниченных строк:
pcregrep -Mi "(?s)<title>.*</title>" example.html
Ответ 6
С помощью серебряного искателя:
ag 'abc.*(\n|.)*efg'
Оптимизация скорости искателя серебра могла бы сиять здесь.
Ответ 7
Вы можете использовать альтернативный просеиватель grep здесь (отказ от ответственности: я автор).
Он поддерживает многострочное сопоставление и ограничение поиска по конкретным типам файлов из коробки:
sift -m --files '*.py' 'YOUR_PATTERN'
(найдите все *.py файлы для указанного многострочного шаблона регулярного выражения)
Он доступен для всех основных операционных систем. Взгляните на страницу образцов, чтобы узнать, как ее можно использовать для извлечения многострочных значений из файла XML.
Ответ 8
Этот ответ может быть полезен:
Regex (grep) для многострочного поиска
Чтобы найти рекурсивно, вы можете использовать флаги -R (рекурсивный) и --include (шаблон GLOB). Видеть:
Используйте синтаксис grep --exclude / --include, чтобы не grep через определенные файлы
Ответ 9
perl -ne 'print if (/begin pattern/../end pattern/)' filename
Ответ 10
@Marcin:
awk пример не-жадный:
awk '{if ($0 ~ /Start pattern/) {triggered=1;}if (triggered) {print; if ($0 ~ /End pattern/) { exit;}}}' filename
Ответ 11
Использование 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).