我有 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>
命令行中的文件顺序是重要的。