Есть ли многострочный grep? Выручит awk

Часто при работе в Linux пользуюсь утилитой grep. Как же я рад, что есть такая мощная утилита. Особенно мне нравится ее использовать с флагом -P — данная опция дает возможность использовать регулярные выражения в стиле Perl. Но многократно сталкивался с проблемой — grep не может работать с многострочными регулярными выражениями. Но для себя я нашел выходы из некоторых ситуаций.

Данные факты и хочу изложить в этой небольшой статье. Статья в основном предназначена для «собственной памяти», так как в основном получается обходиться простыми регулярными выражениями, а когда возникает потребность решить сложную задачу, то уже даже не вспомнить как ты это делал в прошлый раз.  Итак, для того, чтобы найти «от сих и до сих» можно использовать еще одну замечательную unix утилиту — awk. Думаю, я не раз еще упомяну ее. Команда приведенная ниже, позволяет выделить все что подпадает под шаблон от »Start pattern» до «End pattern»

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

Так же можно использовать и не с файлами, а со стандартными вводами-выводами:

... | awk '/Start pattern/,/End pattern/' | ...

Ниже приведу примеры с комментариями:

#Просто использование grep вычленит только строки с condition
root@localhost#
$ echo ' <extension name="queues">
 <condition field="destination_number" expression="^(4\d\d\d)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="$1"/>
 </condition>
 </extension>
 <extension name="1020">
 <condition field="destination_number" expression="^(1020)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="4031"/>
 </condition>
 </extension>' | grep condition
# Получаем:
 <condition field="destination_number" expression="^(4\d\d\d)$">
 </condition>
 <condition field="destination_number" expression="^(1020)$">
 </condition>


#Использование awk позволяет найти все
#вхождения от "<condition" и до "</condition>"
#Не забываем экранировать косую "<\/condition>"
root@localhost#
$ echo ' <extension name="queues">
 <condition field="destination_number" expression="^(4\d\d\d)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="$1"/>
 </condition>
 </extension>
 <extension name="1020">
 <condition field="destination_number" expression="^(1020)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="4031"/>
 </condition>
 </extension>' | awk '/<condition/,/<\/condition>/'
# Получаем:
 <condition field="destination_number" expression="^(4\d\d\d)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="$1"/>
 </condition>
 <condition field="destination_number" expression="^(1020)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="4031"/>
 </condition>

#В данной конкретной ситуации похожего результата можно добиться
#с помощью инвертирующей опции для grep "-v" (все кроме шаблона)
root@localhost#
$ echo ' <extension name="queues">
 <condition field="destination_number" expression="^(4\d\d\d)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="$1"/>
 </condition>
 </extension>
 <extension name="1020">
 <condition field="destination_number" expression="^(1020)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="4031"/>
 </condition>
 </extension>' | grep -v 'extension'
# Получаем:
 <condition field="destination_number" expression="^(4\d\d\d)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="$1"/>
 </condition>
 <condition field="destination_number" expression="^(1020)$">
 <action application="ring_ready" />
 <action application="set" data="ringback=${us-ring}"/>
 <action application="start_dtmf"/>
 <action application="callcenter" data="4031"/>
 </condition>

Есть ли многострочный grep? Выручит awk: Один комментарий

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>