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

How can I replace all value fields in an XML file having particular key value using sed or any other Unix tool?

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

例如,我有 file.xml,我想将值更改为 256m,其中有 key= "-Xmx"

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

示例:

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

我想将任何键为 -Xmx 的条目的值替换为 256m

你可以试试下面的方法,

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

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

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

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

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

我知道这并不完全符合您的要求,但我会坚持使用正则表达式来解析 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;

(是的,它不是一行。但这更旨在说明该技术,而不是试图节省击键次数)。