在Ubuntu上的grep中,如何只显示与正则表达式匹配的字符串?

时间:2010-08-06 12:29:01

标签: ubuntu grep

我基本上正在使用正则表达式。在输出中,我想只看到与我的reg exp匹配的字符串。

在一堆XML文件中(大多数是一行中包含大量数据的单行文件),我想得到所有以 MAIL _ 开头的单词。

另外,我希望shell上的grep命令只给出匹配的单词,而不是整行(在这种情况下是整个文件)。

我该怎么做?

我试过了

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

4 个答案:

答案 0 :(得分:16)

首先,使用随Ubuntu安装的GNU grep,-G标志(使用基本regexp)是默认值,因此您可以省略它,但更好的是,使用带-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

答案 1 :(得分:6)

尝试以下命令

grep -Eo 'MAIL_[[:alnum:]_]*'

答案 2 :(得分:2)

grep -o or --only-matching

只输出匹配的文本而不是完整的行,但问题可能是你的正则表达不是限制性或贪婪,实际上匹配整个文件。

答案 3 :(得分:0)

从您的评论到Thor的回答,似乎您还想区分MAIL_.*文本是文本节点还是属性,而不仅仅是在XML文档中出现时将其隔离。 Grep无法解析XML you need a proper XML parser for that

命令行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表达式,用于选择文档中的所有属性,然后@*输出其值