2017-08-09 211 views
-1

我有两个XML文件,我想复制和粘贴与SED

  1. 文件中查找特定的XML节点A
  2. 复制
  3. 找到一个特定的部分中的文件B文件B
  4. 粘贴复制的节点。

sed中已被使用在我的机器上,但我在寻找合适的正则表达式配置的麻烦。

实施例用于文件A:

<Containers> 
    <Container id="1"> <-- to be copied start 
    blubb 
    </Container> <-- to be copied end 
    <Container id="2">blobb</Container> 
</Containers> 

实施例用于文件B:

<Containers> 
    <Container id="1"> <-- copied here start 
    blubb 
    </Container> <-- copied here end 
    <Container id="99">blibb</Container> 
</Containers> 

我做的:

<Containers> 
    <Container id="99">blibb</Container> 
</Containers> 

通过从<Container id="1"切割成</Container>以获得所需的输出文件B实施例知道它会更干净,也许更容易使用XML解析器和其他工具,但我需要使用sed,我不是一个非常有经验的sed/regex用户。我只是打得四处“替代”和“删除”一点点,但仅此而已......

我愿澄清:

  • 我需要使用sed的,因为这是唯一的工具可用在机器上。
  • 我知道,我能做到这一点在其他编程语言和其他工具,但在这里,这是不可能的。应该运行的机器不在我的控制之下!

我知道我不应该使用正则表达式的XML/XHTML - 我知道,但地球是复杂得多。

我cygwin的版本运行此。

更新1:

几个反应。由于这似乎是不可能找到与SED的解决方案。 感谢所有了解这个问题,并试图帮助!

如果有人仍然可以看到一个潜在的解决方案,那么请让我知道。但挑战在于使用sed。我已经使用XML解析器与提升,QT,C#,Java的,......但是,这里根本就不是问题,如果我可以选择......我不能。

更新2:

谢谢大家,特别是本杰明W.这是绝对有可能使用SED来解决这个问题,而是多次表示,如果你必须使用一个XML解析lib和另一可能性技术,那么这应该是一条路。

对我来说,一个非技术问题(伪安全指南)已经解决了与现有的技术解决方案。

这是我的最终解决方案:

sed "/<Container id=\"1\">/,/<\/Container>/!d" fileA.xml |^
sed -i "/<Containers>/r /dev/stdin" fileB.xml 

谢谢。

+0

Ruby,Perl,Python,Swift,都有简单的xml解析器。不要尝试使用面向行的1980年代ERE正则表达式工具来解析面向块的语法。 Square peg =>圆孔。不要使用锤子。 – dawg

+0

*我不是一个非常有经验的sed/regex用户*这是一种不好的方法来尝试和学习... – dawg

+0

我认为你错过了一点 - 使用Regex解析任意XML比“更困难”更糟糕,这实际上在逻辑上是不可能的。如果您不能使用XML解析器,那么您无法执行该项目。 – EJoshuaS

回答

5

这是一个sed命令,可以完成示例要求的操作。让我先介绍它,然后列出将如何突破:产生

<Containers> 
    <Container id="1"> 
    blubb 
    </Container> 
    <Container id="99">blibb</Container> 
</Containers> 

这需要GNU的sed从特殊文件/dev/stdin读取标准输入

sed '/<Container id="1">/,/<\/Container>/!d' fileA.xml | 
    sed '/<Containers>/r /dev/stdin' fileB.xml 

;没有GNU sed,第一个命令的输出可以保存到临时文件中,然后从那里读取。

第一条命令查找以匹配<Container id="1">并以匹配<\/Container>匹配的行结尾的行开始。该范围外的所有外部被删除。

第二个命令查找匹配<Containers>的行,然后插入第一个命令的输出与r

下面是如何能突破:

  • 空白中的任何变化(<Container id="1">和它打破)
  • 在换行符
    • 在同一行打开标签关闭标签的任何差异:在休息
    • <Containers>不上自己的一条线:在休息
    • 下一个节点上的同一行开始为关闭标签</Container>:休息
  • ID为1
  • 任何其他<Containers>节点其他地方的任何<Container>子节点fileB.xml
  • 用相同的节点名称

...等等任何嵌套。

正如在评论中指出的那样,这应该是最后一招。或许你最好把你的输入文件复制到一台拥有适当工具的机器上,然后将它们复制回来,而不是使用它。