В grep на Ubuntu, как я могу отобразить только строку, которая соответствует регулярному выражению? - PullRequest
12 голосов
/ 06 августа 2010

Я в основном схожу с регулярным выражением.В выводе я хотел бы видеть только те строки, которые соответствуют моему регулярному выражению.

В группе файлов XML (в основном это однострочные файлы с огромным количеством данных в строке), я быхотел бы получить все слова, начинающиеся с MAIL_ .

Кроме того, я хотел бы, чтобы команда grep на оболочке выдавала только совпадающие слова, а не всю строку (которая являетсявесь файл в данном случае).

Как мне это сделать?

Я пытался

grep -Gril MAIL_* .
grep -Grio MAIL_* .
grep -Gro MAIL_* .

Ответы [ 4 ]

16 голосов
/ 06 августа 2010

Прежде всего, с GNU grep, который установлен с Ubuntu, по умолчанию используется флаг -G (используйте базовое регулярное выражение), поэтому вы можете его опустить, но, что еще лучше, используйте расширенное регулярное выражение с -E.

-r флаг означает рекурсивный поиск в файлах каталога, это то, что вам нужно.

И вы вправе использовать флаг -o для печати соответствующей части строки. Также, чтобы пропустить имена файлов, вам понадобится флаг -h.

Единственная ошибка, которую вы допустили, это само регулярное выражение. Вы пропустили спецификацию персонажа до *. Ваша команда должна выглядеть так:

grep -Ehro 'MAIL_[^[:space:]]*' .

Пример вывода (не рекурсивный):

$ echo "Some garbage MAIL_OPTION comes MAIL_VALUE here" | grep -Eho 'MAIL_[^[:space:]]*'
MAIL_OPTION
MAIL_VALUE
6 голосов
/ 06 августа 2010

Попробуйте следующую команду

grep -Eo 'MAIL_[[:alnum:]_]*'
2 голосов
/ 06 августа 2010
grep -o or --only-matching

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

0 голосов
/ 07 августа 2010

Из вашего комментария к ответу Тора кажется, что вы также хотите различить, является ли текст MAIL_.* текстовым узлом или атрибутом, а не просто изолировать его всякий раз, когда он появляется в документе XML. Grep не может разобрать XML, для этого вам нужен правильный анализатор XML .

Анализатор xml командной строки: xmlstarlet . Он упакован в Ubuntu.

Использование его в этом примере файла примера файла:

$ cat test.xml 
<some_root>
    <test a="MAIL_as_attribute">will be printed if you want matching attributes</test>
    <bar>MAIL_as_text will be printed if you want matching text nodes</bar>
    <MAIL_will_not_be_printed>abc</MAIL_will_not_be_printed>
</some_root>

Для выбора текстовых узлов вы можете использовать:

$ xmlstarlet sel -t -m '//*' -v 'text()' -n test.xml | grep -Eo 'MAIL_[^[:space:]]*'
MAIL_as_text

А для выбора атрибутов:

$ xmlstarlet sel -t -m '//*[@*]' -v '@*' -n test.xml | grep -Eo 'MAIL_[^[:space:]]*'
MAIL_as_attribute

Краткие пояснения:

  • //* - это выражение XPath, которое выбирает все элементы в документе и text() выводит значение их дочерних текстовых узлов, поэтому все, кроме текстовых узлов, отфильтровывается
  • //*[@*] - это выражение XPath, которое выбирает все атрибуты в документе, а затем @* выводит их значение
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...