Есть ли способ вести grep
журнал и находить текст между разделителями записей журнала? Наш файл журнала разделяет записи строк символами " -------
" Поэтому, когда я ищу текстовое слово, мне нужны все строки до и после разделителей в журнале.
Образец журнала
------------------------------------------------------------------------
r132279 | USERID | 2014-04-30 12:59:09 -0700 (Wed, 30 Apr 2014) | 3 lines
Removed unused "Calculated Fields" column entry.
Jira ID: JIRA-977
------------------------------------------------------------------------
В примере выше я бы выполнил команду Grep для слова Fields, но мне нужны все строки между ----
строками " "
решение1
Если вы знаете размер записи, то вы можете вывести дополнительные строки контекста перед ( -B
) и после ( -A
) совпадающей строки, например
grep -A2 -B2 'Fields' sample.log
или для контекста как до, так и после линии соответствия
grep -C3 'Fields' sample.log
Насколько мне известно, единственный способ сделать настоящее многострочное совпадение (а не однострочное совпадение плюс контекст) в GNU grep — это использовать режим регулярных выражений PCRE ( -P
) с -z
флагом предотвращения разрыва на новых строках. Например, вы можете попробовать
grep -zPo '(\n-+\n)\K(.|\n)+?Fields(.|\n)+?(?=\n-+\n)'
который выполняет нежадное сопоставление строки, Fields
окруженной любыми символами ИЛИ символами новой строки, при условии, что она заключена вновая строка-дефисы-новая строкаразделители. Эквивалентное выражение в pcregrep:
pcregrep -Mo '(\n-+\n)\K(.|\n)+?Fields(.|\n)+?(?=\n-+\n)'
Другим вариантом для такого рода структурированных записей данных является awk: в частности, GNU awk позволяет использовать регулярное выражение для внутреннегоразделитель записейRS например
$ gawk -vRS='\n-+\n' '/Fields/ {print}' sample.log
r132279 | USERID | 2014-04-30 12:59:09 -0700 (Wed, 30 Apr 2014) | 3 lines
Removed unused "Calculated Fields" column entry.
Jira ID: JIRA-977
решение2
Решение Perl, похожее на gawk
то, что вответ стального водителяв случае gawk
отсутствия:
perl -ne 'BEGIN{$/= "-"x72 . "\n"} chomp and print if /Fields/' log_file
Замените 72 фактическим количеством дефисов в вашем разделителе.