20

我正在编写一个 bash 脚本来从 xml 文件中提取一些信息。我正在使用grep这个。

为了找到我需要的信息,我运行:

grep -oP "<title>(.*)</title>" temp.xml

我得到一个匹配列表,其中包括<title>标签。

如何使用 grep获取仅包含title标签内文本但包含标签的列表?title

4

6 回答 6

37

既然你已经使用了grep -P,为什么不使用它的功能呢?

grep -oP '(?<=<title>).*?(?=</title>)'

在一般情况下,XPath 是正确的解决方案,但对于玩具场景,是的,Virginia,它可以做到。

于 2012-05-28T10:50:58.623 回答
8

我不明白你为什么要为此使用 grep,虽然它可以用一个简单的 XPath 表达式来解决:

//title/text()

XPath 有许多命令行工具,它们通常与操作系统捆绑在一起。

Stack Overflow 上对这个问题的回答列出了许多这样的工具。

这里的问题grep是它是一个通用的文本处理工具,它不知道任何 XML 结构。对于一个非常简单的场景,您可以让它工作。如果文档很复杂,或者如果您在一个脚本中使用它,该脚本可以存活数月或数年,而不仅仅是一次性工作,您最终可能会对结果感到抱歉。

XPath 可以很容易地区分出现在文档中不同上下文中的类似名称的标签。

<article>
    <author>
        <name>Jon Doe</name>
        <title>Chief Editor</title>
    </author>
    <title>On the Benefits of grep</title>
    <publicationDate>2018-02-12</publicationDate>
    <text>blah blah blah</text>
</article>

如果您使用此处发布的任何其他答案,则提取本文档所代表的文章标题grep将失败。从技术上讲,您可以编写正则表达式来获得所需的内容,但使用 XPath 会容易得多。

/article/title/text()

如果您知道您正在处理一个琐碎的文档并且格式没有改变,或者如果这是您可以快速验证结果的一次性工作,您可以grep按照其他人的解释进行。

于 2012-05-28T09:55:08.573 回答
5

这不是最好的解决方案,我会在 bash 中搜索 XML lib,但你可以这样做:

grep -oP "<title>(.*)</title>" temp.xml | cut -d ">" -f 2 | cut -d "<" -f 1
于 2012-05-28T09:10:18.760 回答
2
grep -oP "<foo>(.*)</foo>" "XML.xml" | sed -n 's/.*<foo>\([^<]*\)<\/foo>.*/\1/p' >> "foo.txt"
于 2019-01-16T06:17:11.343 回答
1

您可以按照Tom的回答中的建议使用 xpath 安装 xgrep

人 xgrep

于 2013-02-11T15:25:50.793 回答
0

您可以使用以下任何命令来获取标签之间的值。

grep -oP '(>).*?(?=</title>)' test.xml | cut -d ">" -f 2
grep -oP '(?<=title>).*(?=</title)' test.xml
awk -F "[><]" '/title/{print $3}' test.xml

于 2021-02-27T02:01:21.930 回答