如何在 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>
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"
... 在出现所有
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>