0

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

Example, I have file.xml with me and I want to change the value to 256m which has key= "-Xmx"

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

Example:

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

I want to replace value as 256m for any entry having key as -Xmx.

jub0bs
  • 60,866
  • 25
  • 183
  • 186
gtaware
  • 103
  • 5
  • It's not recommended, because pretty fundamentally XML is NOT regex friendly. Sometimes it'll work, but it's not reliable. Is perl an option? See: http://stackoverflow.com/questions/701166/can-you-provide-some-examples-of-why-it-is-hard-to-parse-xml-and-html-with-a-reg and http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – Sobrique Feb 24 '15 at 13:32

3 Answers3

3

Editing XML with sed is not a good idea, since sed works on lines and XML is not a line-based format. You will end up with solutions that break as soon as attributes are specified in a different order, with other attributes between them or on different lines -- all of which is allowed in XML but difficult to handle for sed.

Instead, use a proper XML-handling tool like xmlstarlet:

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

where //entry[@key="-Xmx"]/@value is an XPath expression selecting the value attribute of all entry nodes whose key attribute is -Xmx, and xmlstarlet ed -u xpath -v value sets the value of the selected XPath.

Wintermute
  • 42,983
  • 5
  • 77
  • 80
0

You could try the below,

$ echo '<entry key="-Xmx" value="512m" />' | sed 's/\b\(key="-Xmx" *value="\)[^"]*m"/\1256m"/g'
<entry key="-Xmx" value="256m" />
Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
  • How would I know that this replacement is taking place in my file sample.xml only? As I can not see any input paramater here. Thanks. – gtaware Feb 24 '15 at 13:38
  • add `i` parameter to save the changes made. like `sed -i 's/\b\(key="-Xmx" *value="\)[^"]*m"/\1256m"/g' file.xml` – Avinash Raj Feb 24 '15 at 13:39
0

I know it's not quite what you asked for, but I'll stand by my assertion that using regex for parsing XML is a bad idea.

See: 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?

So I'd be thinking perlishly:

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

(And yes, it's not a one liner. But this is more aimed at being illustrative of the technique, rather than trying to save keystrokes).

Community
  • 1
  • 1
Sobrique
  • 52,974
  • 7
  • 60
  • 101