12

Как мне найти фразу в нескольких строках? Например, давайте напишем фразу "мой ледяной чай", тогда она может быть обернута в текстовые файлы:

as js skdfh dfh djh sf my
ice tea.

grep не будет совпадать, так как между ними есть новая строка. Как мне соответствовать этим? Другой многострочный шаблон будет pattern1_\n_pattern2

Я знаю, что самый простой способ, которым я делаю ATM, это просто grep для одной части, например, лед с флагом -A2 -B2 и затем в этом выходе, например, чай. Но это очень утомительно. Поэтому я заинтересован в том, как бы вы решили это.

4 ответа4

14

Вы можете установить pcregrep (доступный в большинстве дистрибутивов) - это grep с использованием библиотеки pcre, которая выполняет "Perl-совместимые регулярные выражения". Он имеет параметр командной строки -M который позволяет выполнять многострочный поиск - со страницы руководства:

«Вывод для любого совпадения может состоять из нескольких строк».

Так что вы могли бы сделать

pcregrep -M 'my\s+ice\s+tea' filename

\s - это пробел, который будет соответствовать \n и \r в многострочном режиме, в дополнение к обычным пробелам. Вы также можете напрямую сопоставить символ новой строки, чтобы вы могли сделать

pcregrep -M 'pattern1_\n_pattern2' filename
3

Я бы, вероятно, сделал поиск с помощью команды vim 's :vimgrep . Это работает примерно так же, как в grep но поддерживает vim RE и пути.

В основном вы запускаете что - то :vimgrep 'pattern1\npattern2' path/** для рекурсивного поиска, а затем :copen , чтобы открыть окно меньшего размера , содержащее список совпадений.

vim RE могут делать в основном все, что могут PCRE, но они развивались отдельно от линии регулярных выражений perl, поэтому большинство продвинутых вещей работают по-другому. Их базовая функциональность больше похожа на базовые RE, но у них есть некоторые изящные дополнения, которые PCRE не предлагают.

Я не уверен, возможно ли получить :vimgrep выкладывать данные, как это делает grep ; Я только пытался использовать его для навигации в vim .

:help vimgrep изнутри vim для получения дополнительной информации; :help pattern.txt для получения информации о vim RE; для получения дополнительной информации о путях смотрите :help wildcards .

2

Grep работает только по одной строке за раз, но вы можете использовать awk для печати строк, соответствующих ряду шаблонов:

cat file | awk '/foo/,/bar/'

это будет соответствовать чему угодно, а не только переводу строк между двумя шаблонами

0

Чтобы получить максимальную отдачу от Unix, вам нужно использовать преимущества труб. Вы можете сделать это в обычном grep используя трубы (нет необходимости в тройнике):

$ grep -A1 "pattern1" file.txt |  grep "pattern2"

Что я не считаю утомительным.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .