如何使用sed或Unix中的任何其他命令替换具有特定键值的XML文件中的所有值字段?
例如,我有file.xml
,我想将值更改为具有key= "-Xmx"
的256m
<entry key="-Xmx" value="512m" />
示例:
<entry key="-Xmx" value="512m" />
我想将关键字为-Xmx
的任何条目的值替换为256m
。
使用sed编辑XML不是一个好主意,因为sed在行上工作,而XML不是基于行的格式。一旦以不同的顺序指定了属性,在它们之间或在不同的行上指定了其他属性,那么最终就会出现中断的解决方案——所有这些在XML中都是允许的,但对于sed来说很难处理。
相反,可以使用适当的XML处理工具,如xmlstarlet
:
xmlstarlet ed -u '//entry[@key="-Xmx"]/@value' -v 256m filename.xml
其中,//entry[@key="-Xmx"]/@value
是选择key
属性为-Xmx
的所有entry
节点的value
属性的XPath表达式,xmlstarlet ed -u xpath -v value
设置所选XPath的值。
您可以尝试以下方法,
$ echo '<entry key="-Xmx" value="512m" />' | sed 's/b(key="-Xmx" *value=")[^"]*m"/1256m"/g'
<entry key="-Xmx" value="256m" />
我知道这不是您所要求的,但我会坚持我的主张,即使用正则表达式解析XML是个坏主意。
请参阅:RegEx匹配除XHTML自带标签之外的开放标签
你能举几个例子说明为什么用正则表达式解析XML和HTML很困难吗?
所以我会错误地思考:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $xml = '<XML>
<entry key="-Xmx" value="512m" />
</XML>';
sub amend_entry {
my ( $twig, $entry ) = @_;
if ( $entry->att('key') eq '-Xmx' ) {
$entry->set_att( 'value' => "256m" );
}
}
my $parser = XML::Twig->new( twig_handlers => { entry => &amend_entry } )
->parse($xml)->print;
(是的,这不是一句话。但这更多的是为了说明这项技术,而不是试图节省击键次数)。