如何在 XML 文件中的单词后添加变量内容

how to add content of variable after word in XML file

ADD_XML变量包括以下

echo "$ADD_XML"
 <units>
 <unit ip="10.106.5.8" unit_type="RECOGNIZE Discovery"/>
 <unit ip="10.106.3.21" unit_type="RECOGNIZE Discovery"/>
 <unit ip="10.106.3.12" unit_type="RECOGNIZE Discovery"/>
 <unit ip="10.106.3.13" unit_type="RECOGNIZE Discovery"/>
 </units>
 <ranges/>
 </Networks>

我要在第一个之后添加$ADD_XML的内容:

 <Networks> 

在我的 XML 文件中

请建议如何通过 sed/awk 或 perl 一行

实现

示例它应该如何出现在 XML 文件中

 </Networks>
 <units>
 <unit ip="10.106.5.8" unit_type="RECOGNIZE Discovery"/>
 <unit ip="10.106.3.21" unit_type="RECOGNIZE Discovery"/>
 <unit ip="10.106.3.12" unit_type="RECOGNIZE Discovery"/>
 <unit ip="10.106.3.13" unit_type="RECOGNIZE Discovery"/>
 </units>
 <ranges/>
  </Networks>
sed -e "/<Networks>/a \
$ADD_XML"

... 在出现所有 后添加 $ADD_XML。

sed -e "1,/<Networks>/s@<Networks>@&\n$ADD_XML@"

... 仅在第一次出现时有效。如果 $ADD_XML 包含 '@' 字符,您需要使用不同的字符($ADD_XML 中未使用的字符)或按照其他答案的建议寻求更复杂的解决方案。

你想要像下面这样的东西awk:

    awk '[=10=] == "<Networks>"{print; print "'$ADD_XML'"}'
echo "${ADD_XML}" >/tmp/Add.XML
sed '1,\#</Networks># {
        \#</Networks># {
           p
           r /tmp/Add.XML
           }
        }
    ' YourFile
rm /tmp/Add.XML
  • 使用临时文件和r sed 操作(读取和写入文件内容)
  • 子部分只在第一个插入Network
  • 只是 p 需要在插入文件之前打印 Network 的最后一行(r 替换当前 [buffer] 行的输出)

这可能对你有用(GNU sed & bash):

sed '/<Networks>/r /dev/stdin' <<<"$ADD_XML" file

这会在 <Networks> 之后使用标准输入作为文件读取 $ADD_XML 的内容。

如果可能有多个 <Network> 标签使用:

sed $'1,/<Networks>/{/<Networks>/r /dev/stdin\n}' <<<"$ADD_XML" file

我会重复我在 "Unix"

上说过的话

不要这样做。

用正则表达式解析 XML 很混乱而且会中断。您可以使用 XML 做很多有效的事情,这些事情会搞砸正则表达式。 (最简单和最明显的是 - 漂亮的打印给你有效的 XML,但会破坏正则表达式)。同样,故意创建格式错误的 XML 非常令人讨厌,而且容易搞砸。

另请参阅:Dealing with malformed XML

并且:RegEx match open tags except XHTML self-contained tags

所以不要这样做。使用解析器。

像这样应该可以满足您的需要(如果您可以包含稍微大一点的源数据样本,我可以修改):

#!/usr/bin/perl
use strict;
use warnings;

use XML::Twig;

my $xml_text = '<XML>
<Networks><units><unit ip="1.2.3.4" /></units><ranges/></Networks>
</XML>';

my $original = XML::Twig->new( 'pretty_print' => 'indented' );
#would probably use 'parsefile' instead here
$original->parse($xml_text);

print "\nBefore:\n";
$original->print;


#read update:

my $to_insert =  XML::Twig->new -> parse ( \*DATA );

#insert a new element into 'Networks':
foreach my $unit ( $to_insert -> root -> children ) {
    $unit -> cut();
    $unit -> paste ( $original->root->first_child('Networks')->first_child('units') );
}


print "\nAfter:\n";
$original->print;


__DATA__
 <units>
 <unit ip="10.106.5.8" unit_type="RECOGNIZE Discovery"/>
 <unit ip="10.106.3.21" unit_type="RECOGNIZE Discovery"/>
 <unit ip="10.106.3.12" unit_type="RECOGNIZE Discovery"/>
 <unit ip="10.106.3.13" unit_type="RECOGNIZE Discovery"/>  
 </units>