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

时间:2015-02-24 13:29:18

标签: xml linux unix sed

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

示例,我有file.xml跟我一起,我想将值更改为256m key= "-Xmx"

<entry key="-Xmx" value="512m" />

示例:

<entry key="-Xmx" value="512m" />

对于密钥为256m的任何条目,我想将值替换为-Xmx

3 个答案:

答案 0 :(得分:3)

使用sed编辑XML不是一个好主意,因为sed适用于行,而XML不是基于行的格式。一旦以不同的顺序指定属性,在它们之间或在不同的行上指定其他属性,您将最终得到中断的解决方案 - 所有这些都在XML中允许但是对于sed来说很难处理。

相反,请使用适当的XML处理工具,例如xmlstarlet

xmlstarlet ed -u '//entry[@key="-Xmx"]/@value' -v 256m filename.xml

其中//entry[@key="-Xmx"]/@value是一个XPath表达式,选择value属性为entry的所有key个节点的-Xmx属性,xmlstarlet ed -u xpath -v value个集合所选XPath的值。

答案 1 :(得分:0)

您可以尝试下面的内容,

$ echo '<entry key="-Xmx" value="512m" />' | sed 's/\b\(key="-Xmx" *value="\)[^"]*m"/\1256m"/g'
<entry key="-Xmx" value="256m" />

答案 2 :(得分:0)

我知道这不是你要求的,但我会坚持认为使用正则表达式来解析XML是一个坏主意。

请参阅:RegEx match open tags except XHTML self-contained tags

Can you provide some examples of why it is hard to parse XML and HTML with a regex?

所以我会想到的是:

#!/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;

(是的,它不是一个单行。但这更多的目的是说明技术,而不是试图保存击键)。