如何使用SED提取特定的XML节点

如何使用SED提取特定的XML节点,xml,unix,sed,Xml,Unix,Sed,第一次在这里发布,但不是第一次使用堆栈溢出作为资源。必须说,这个网站一直是我的整体工作 我以前在很多方面使用过sed,但似乎不知道如何返回完整的XML节点,如果且仅当它的一个子节点满足某些条件。我知道如何使用2地址约定(/START/END/command),但需要将结果仅限于特定的匹配子节点 例如: <entity id="001"> <name>Jane Doe</name> <country>US</country>

第一次在这里发布,但不是第一次使用堆栈溢出作为资源。必须说,这个网站一直是我的整体工作

我以前在很多方面使用过
sed
,但似乎不知道如何返回完整的XML节点,如果且仅当它的一个子节点满足某些条件。我知道如何使用2地址约定(
/START/END/command
),但需要将结果仅限于特定的匹配子节点

例如:

<entity id="001">
    <name>Jane Doe</name>
    <country>US</country>
</entity>
<entity id="002">
    <name>Jose Reyes</name>
    <country>Mexico</country>
</entity>
<entity id="003">
    <name>Juan Dela Cruz</name>
    <country>Philippines</country>
</entity>
<entity id="004">
    <name>William Shatner</name>
    <country>US</country>
</entity>
但是,如果我想返回与国家/地区
美国
匹配的完整实体节点,我应该如何执行该操作

如果你能给我指一个大致的方向,我不介意自己做这项工作。事实上,比起用勺子喂食,我更喜欢那个


谢谢

正如您在对类似问题的评论中所看到的,处理XML最好的工具是为处理XML而设计的,而不是像sed或awk这样的通用文本处理工具

例如,如果您有权访问
xmlstarlet

$ xmlstarlet sel -t -c "//entity[country = 'US']" file.xml
<entity id="001">
    <name>Jane Doe</name>
    <country>US</country>
</entity><entity id="004">
    <name>William Shatner</name>
    <country>US</country>
</entity>

非常感谢。我一定会研究
xmlstarlet
工具。我只是想知道是否可以使用
sed
这是唯一可用的工具,因为我可能无法在客户的服务器上安装其他工具。我完全理解不一定要控制目标环境,就是这样!我添加了一个awk解决方案(如果您使用sed,您肯定也会使用awk)。请注意,这是一种更脆弱的情况,取决于XML是否以某种方式格式化,而基于xpath的解决方案只取决于XML是否有效。谢谢!我更喜欢
xmlstarlet
解决方案。与
xpath
表达式相结合,这无疑是用于命令行XML解析(或类似)的更好工具。如果需要,应该能够找到一种方法将其介绍给客户的环境。我当然可以在我本地的cygwin安装中运行它。我完全同意
awk
脚本将取决于XML的格式。
$ xmlstarlet sel -t -c "//entity[country = 'US']" file.xml
<entity id="001">
    <name>Jane Doe</name>
    <country>US</country>
</entity><entity id="004">
    <name>William Shatner</name>
    <country>US</country>
</entity>
$ cat a.awk

/<entity id/ { f = 1; s = "" }

f { s = s ? (s ORS $0) : $0 }

/<country>US</ { f = 2 }

/<\/entity>/ {
    if (f == 2) print s
    f = 0
}

$ awk -f a.awk file.xml
  <entity id="001">
    <name>Jane Doe</name>
    <country>US</country>
  </entity>
  <entity id="004">
    <name>William Shatner</name>
    <country>US</country>
  </entity>