我正在编写一个 bash 脚本来从 xml 文件中提取一些信息。我正在使用grep
这个。
为了找到我需要的信息,我运行:
grep -oP "<title>(.*)</title>" temp.xml
我得到一个匹配列表,其中包括<title>
标签。
如何使用 grep获取仅包含title
标签内文本但不包含标签的列表?title
既然你已经使用了grep -P
,为什么不使用它的功能呢?
grep -oP '(?<=<title>).*?(?=</title>)'
在一般情况下,XPath 是正确的解决方案,但对于玩具场景,是的,Virginia,它可以做到。
我不明白你为什么要为此使用 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
按照其他人的解释进行。
这不是最好的解决方案,我会在 bash 中搜索 XML lib,但你可以这样做:
grep -oP "<title>(.*)</title>" temp.xml | cut -d ">" -f 2 | cut -d "<" -f 1
grep -oP "<foo>(.*)</foo>" "XML.xml" | sed -n 's/.*<foo>\([^<]*\)<\/foo>.*/\1/p' >> "foo.txt"
您可以使用以下任何命令来获取标签之间的值。
grep -oP '(>).*?(?=</title>)' test.xml | cut -d ">" -f 2
grep -oP '(?<=title>).*(?=</title)' test.xml
awk -F "[><]" '/title/{print $3}' test.xml