仅将一个 xml 文件的新条目合并到另一个 xml 文件中

仅将一个 xml 文件的新条目合并到另一个 xml 文件中

我有 2 个 xml 文件。第 2 个文件有一些新条目,其中包括与第 1 个文件相同的条目。下面给出了 2 个文件的示例。

文件 1

<SERVERNAME_ONE>
        <Protocol>FTP</Protocol>
        <ServerIP>192.168.0.231</ServerIP>
</SERVERNAME_ONE>

文件 2

<SERVERNAME_ONE>
        <Protocol>FTP</Protocol>
        <ServerIP>192.168.1.21</ServerIP>
</SERVERNAME_ONE>
<SERVERNAME_TWO>
        <Protocol>FTP</Protocol>
        <ServerIP>192.168.13.231</ServerIP>
</SERVERNAME_TWO>

合并后

<SERVERNAME_ONE>
        <Protocol>FTP</Protocol>
        <ServerIP>192.168.0.231</ServerIP>
</SERVERNAME_ONE>
<SERVERNAME_TWO>
        <Protocol>FTP</Protocol>
        <ServerIP>192.168.13.231</ServerIP>
</SERVERNAME_TWO>

当我将第二个文件与第一个文件合并时,合并应以这样的方式进行:只有第二个文件中的新条目必须合并,即第一个文件中已经存在的条目必须保持原样。有 sdiff 命令可以交互合并。但我想自动执行合并过程。如何合并这些文件?

答案1

XML 可能并且通常很难用老式的 shell 工具来处理;必须使用 XML 解析器来查找节点。但是,如果且仅当您的文件格式真的像写的那样简单(始终有换行符,重要标签不嵌套在其他标签中,并且它们开始行),那么可以使用起始标签到结束标签的模式匹配来完成。

 $ cat mergexml.awk

FILENAME!=fn { ++fcnt; fn = FILENAME }

fcnt == 1 {
   print
   str = $0
   if ( inside ) {
      if ( str ~ "^ *</ *" tag " *> *$") {
         inside = 0
      }
   } else {
      gsub( /^ *< *| *> *$/, "", str)
      if ( str ~ /^[[:alnum:]_]+$/) {
         tag = str
         f1tags[tag] = ""
         inside = 1
      }
   }
}

fcnt == 2 {
   str = $0
   if ( inside ) {
      print
      if ( str ~ "^ *</ *" tag " *> *$") {
         inside = 0
      }
   } else {
      gsub( /^ *< *| *> *$/, "", str)
      if ( str ~ /^[[:alnum:]_]+$/) {
         tag = str
         if ( ! (tag in f1tags)) {
            inside = 1
            print
         }
      }
   }
}

$ awk -f mergexml.awk file1 file2
<SERVERNAME_ONE>
        <Protocol>FTP</Protocol>
        <ServerIP>192.168.0.231</ServerIP>
</SERVERNAME_ONE>
<SERVERNAME_TWO>
        <Protocol>FTP</Protocol>
        <ServerIP>192.168.13.231</ServerIP>
</SERVERNAME_TWO>

命令行中的文件顺序是重要的

相关内容