В grep на Ubuntu, как я могу отобразить только строку, которая соответствует регулярному выражению?
Я в основном grepping с регулярным выражением. В выходных данных я хотел бы видеть только строки, соответствующие моему reg exp.
в куче XML-файлов (в основном это однострочные файлы с огромным количеством данных в строке), я хотел бы получить все слова, которые начинаются с MAIL_.
кроме того, я хотел бы, чтобы команда grep в оболочке давала только слова, которые совпадают, а не всю строку (которая является всем файлом в этом случай.)
Как это сделать?
Я пробовал
grep -Gril MAIL_* .
grep -Grio MAIL_* .
grep -Gro MAIL_* .
4 ответов
прежде всего, с GNU grep, который установлен с Ubuntu, флаг-G (использовать базовое регулярное выражение) по умолчанию, поэтому вы можете опустить его, но, еще лучше, использовать расширенное регулярное выражение с-E.
-Р флаг означает рекурсивный поиск в файлах каталога, это то, что вам нужно.
и вы можете использовать флаг-o для печати соответствующей части строки. Кроме того, чтобы опустить имена файлов, вам понадобится флаг a-h.
единственная ошибка, которую вы сделали, - это регулярное выражение. Вы пропущенная спецификация символов перед *. Ваша команда должна выглядеть так:
grep -Ehro 'MAIL_[^[:space:]]*' .
пример вывода (не рекурсивный):
$ echo "Some garbage MAIL_OPTION comes MAIL_VALUE here" | grep -Eho 'MAIL_[^[:space:]]*'
MAIL_OPTION
MAIL_VALUE
grep -o or --only-matching
выводит только соответствующий текст вместо полных строк, но проблема может быть в вашем регулярном выражении, которое не является ограничительным или достаточно жадным и фактически соответствует всему файлу.
из вашего комментария к ответу Тора кажется, что вы также хотите отличить, если MAIL_.*
text-это текстовый узел или атрибут, а не просто изолировать его всякий раз, когда он появляется в 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, которое выбирает все атрибуты в документе, а затем@*
выводит их стоимостью