我有一个如下所示的 xml 文件:
<FileHeader>SampleFile</FileHeader>
<Name>aaaa</Name>
<Place>bufnkf</Place>
<Name> bjfbhj</Name>
<Place>bvdhbf</Place>
<FileFooter><Record>2</Record></FileFooter>
我想提取记录标签的值。使用如下 sed 命令,但它没有给出任何输出:
sed -n '/Record/{s/.*<Record>//;s/<\/Record.*//;p;}' filename
请问对此有什么帮助吗?
答案1
将FileFooter/Record
节点的值放入脚本中的 shell 变量中的最简单方法是使用 XML 解析器,例如xmlstarlet
.
下面假设 XML 文档格式良好,而您的示例文档则不然,因为它具有多个根标记(我假设这是因为您提取了您认为最有趣的位)。它还假设只有一个FileFooter/Record
节点,否则,您将不得不迭代这些值。
value=$( xmlstarlet sel -t -v '//FileFooter/Record' file.xml )
表达式//FileFooter/Record
是我们感兴趣的节点的 XPath(实际上是每个 FileFooter/Record
整个文档中的节点)。通过sel -t -v
,我们告诉我们要提取通过匹配特定的或 XPath ( ) 获得的xmlstarlet
值 ( ) 。-v
sel -t
由于问题中的数据缺少根标签,您可以对其运行以下命令以动态插入缺少的标签,解析更正的文档,并在 shell 变量中提取所需的值value
:
value=$(
{ echo '<root>'; cat file.xml; echo '</root>'; } |
xmlstarlet sel -t -v '//FileFooter/Record'
)
假设缺少的单个根节点被称为root
,您还可以使用xq
(fromhttps://kislyuk.github.io/yq/),围绕 JSON 解析器构建的 XML 解析器层jq
。
value=$( xq -r '.root.FileFooter.Record' file.xml )
.[].FileFooter.Record
如果您不想键入根节点的名称,则可以使用它(FileFooter
不过,这仍然假设它是根节点正下方的节点)。
该命令将 XML 文件转换为 JSON。如果您的 XML 文档如下所示:
<?xml version="1.0"?>
<root>
<FileHeader>SampleFile</FileHeader>
<Name>aaaa</Name>
<Place>bufnkf</Place>
<Name> bjfbhj</Name>
<Place>bvdhbf</Place>
<FileFooter>
<Record>2</Record>
</FileFooter>
</root>
该xq
实用程序会将其转换为以下 JSON 文档:
{
"root": {
"FileHeader": "SampleFile",
"Name": [
"aaaa",
"bjfbhj"
],
"Place": [
"bufnkf",
"bvdhbf"
],
"FileFooter": {
"Record": "2"
}
}
}
xq
然后jq
使用表达式进行调用.root.FileFooter.Record
,提取值。