如何使用sed或任何其他Unix工具替换XML文件中具有特定键值的所有值字段



如何使用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;

(是的,这不是一句话。但这更多的是为了说明这项技术,而不是试图节省击键次数)。

最新更新