Regex 从文件A复制并使用sed粘贴到文件B

Regex 从文件A复制并使用sed粘贴到文件B,regex,sed,Regex,Sed,我有两个XML文件,我想 在文件中查找特定的XML节点 抄写 在文件B中查找特定部分 粘贴复制的节点 sed已经在我的机器上使用了,但是我在找到正确的正则表达式配置时遇到了麻烦 文件A的示例: <Containers> <Container id="1"> <-- to be copied start blubb </Container> <-- to be copied end <Container id="

我有两个XML文件,我想

  • 在文件中查找特定的XML节点
  • 抄写
  • 在文件B中查找特定部分
  • 粘贴复制的节点
  • sed已经在我的机器上使用了,但是我在找到正确的正则表达式配置时遇到了麻烦

    文件A的示例:

    <Containers>
      <Container id="1">    <-- to be copied start
        blubb
      </Container>    <-- to be copied end
      <Container id="2">blobb</Container>
    </Containers>
    
    
    
    下面是一个sed命令,它执行示例要求的操作。让我先介绍一下,然后列出它将如何破坏:

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

    <Containers>
      <Container id="1">
        blubb
      </Container>
      <Container id="99">blibb</Container>
    </Containers>
    
    
    布卢布
    布利布
    
    这需要使用GNU从特殊文件
    /dev/stdin
    读取标准输入;没有GNU sed,第一个命令的输出可以保存到临时文件中,然后从那里读取

    第一个命令查找一个行范围,该行范围以与
    匹配的行开始,以与
    匹配的行结束。超出该范围的所有内容都将被删除

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

    这是如何打破的:

    • 空格中的任何更改(
      ,它会中断)
    • 换行符有什么不同吗
      • 与开始标记在同一行上的结束标记:打断
      • 不单独在一行上:中断
      • 下一个节点与结束标记在同一行上开始:断开
    • ID为1的任何
      子节点
    • fileB.xml
    • 具有相同节点名称的任何嵌套
    …还有更多


    正如评论中指出的那样,这真的应该是最后的手段。您最好将输入文件复制到一台有适当工具的机器上,然后再将它们复制回来,而不是使用这种工具。

    Ruby、Perl、Python、Swift都有简单的xml解析器。不要尝试使用1980年代的ERE正则表达式工具来解析面向块的语法。方桩=>圆孔。不要使用锤子。我不是一个非常有经验的sed/regex用户。这是一种尝试和学习的糟糕方式……我认为你没有抓住要点——使用regex解析任意XML比“更困难”更糟糕,实际上在逻辑上是不可能的。如果你不能使用XML解析器,那么你就不能做这个项目。问题是我被允许做什么。然后通过逻辑扩展:如果您无权访问
    sed
    之外的任何工具,则计算机管理员不希望您编辑xml文件。如果你有awk或Bash,这是可能的,但不是健壮的。sed也可以,只是超级脆弱。我有一条单行线,它完全按照问题的要求去做,但可以在很多很多方面打破它。很可能只解决了最简单的例子。任何不同的事情都会失败,哪怕是一点点。另外,我不是说“使用sed可以解析XML”。我是说“一次性的,容易出错的黑客是可能的”。
    sed "/<Container id=\"1\">/,/<\/Container>/!d" fileA.xml | ^
    sed -i "/<Containers>/r /dev/stdin" fileB.xml
    
    sed '/<Container id="1">/,/<\/Container>/!d' fileA.xml |
        sed '/<Containers>/r /dev/stdin' fileB.xml
    
    <Containers>
      <Container id="1">
        blubb
      </Container>
      <Container id="99">blibb</Container>
    </Containers>