tomasfly123
tomasfly123

Reputation: 25

Replace string in shell using sed or Perl?

How can I replace the following string:

<value>-myValue</value>
          <value>1234</value>

And make it to be:

<value>-myValue</value>
          <value>0</value>

Please take into account that there is a line break.

Upvotes: 0

Views: 79

Answers (3)

Sobrique
Sobrique

Reputation: 53478

You can possibly simplify this a bit, depending on what criteria you specifically want to use:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

my $twig = XML::Twig->new( 'pretty_print' => 'indented_a' )->parse( \*DATA );
foreach my $value ( $twig->findnodes('//value') ) {
    if (    $value->trimmed_text eq '-myValue'
        and $value->next_sibling('value')
        and $value->next_sibling('value')->text =~ m/^\d+$/ )
    {
        $value->next_sibling('value')->set_text('1234');

    }
}

$twig->print;

__DATA__
<root>
<value>-myValue</value>
          <value>0</value>
          </root>

This outputs:

<root>
  <value>-myValue</value>
  <value>1234</value>
</root>
  • It parses your XML.
  • Looks for all nodes with a tag of value.
  • Checks that it has a sibling.
  • Checks that sibling is 'just numeric' e.g. matching regex ^\d+$
  • replaces the content of that sibling with 1234.

And will work on XML regardless of formatting, which is the problem with XML - pretty fundamentally there's a bunch of entirely valid things you can do that are semantically identical in XML.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753675

Script

sed -e '/<value>-myValue</,/<value>/{ /<value>[0-9][0-9]*</ s/[0-9][0-9]*/0/; }' data

From a line containing <value>-myValue< to the next line containing <value>, if the line matches <value>XX< where XX is a string of one or more digits, replace the string of digits with 0.

Input

This is not something to change
<value>-myValue</value>
          <value>1234</value>
<value>myValue</value>
          <value>1234</value>
nonsense
<value>-myValue</value>
          <value>abcd</value>
<value>-myValue</value>
          <value>4321</value>
stuffing

Output

This is not something to change
<value>-myValue</value>
          <value>0</value>
<value>myValue</value>
          <value>1234</value>
nonsense
<value>-myValue</value>
          <value>abcd</value>
<value>-myValue</value>
          <value>0</value>
stuffing

Upvotes: 2

John1024
John1024

Reputation: 113834

If this is XML, TLP is right that an XML parser would be superior. Continuing on with your sed approach, however, consider:

$ sed '/<value>-myValue/ {N; s/<value>[[:digit:]]\+/<value>0/}' file
<value>-myValue</value>
          <value>0</value>

Upvotes: 2

Related Questions