MacUsers
MacUsers

Reputation: 2229

change a portion of a line after a regexp

How do I change a portion of a line after a regexp?

I have a file where I need to modify the line (on the fly) with name = in it but only the one that comes after line with cluster { in it. The file is like this:

cluster {
  name = "Some _ Name"
  owner = "Cavendish Laboratory"
  .....
  .....
}
module {
    name = "core_metrics"
}
service {
    name = "ssh_check"
}
......
......

I can perform this two task separately, like:

sed -n '/cluster\ {/{n;p;}'               # next line after cluster
sed -ic "/name\ =\ /{s:OLD:NEW:g}"        # replace OLD with NEW on the fly

But how do I combine that two to get the end result like: ?

cluster {
  name = "Worker Nodes"
  owner = "Cavendish Laboratory"
  .....
  .....
}

How do I do that? Cheers!

Upvotes: 1

Views: 86

Answers (3)

Dennis Williamson
Dennis Williamson

Reputation: 360105

Here's a Perl one-liner:

perl -ple 'do {$_ =~ s/name = .*/name = "Worker Nodes"/; $flag = 0} if $flag; $flag = 1 if $_ =~ /cluster/' inputfile

Upvotes: 1

potong
potong

Reputation: 58430

This might work for you:

old="Some _ Name" new="Worker Nodes"

sed '/cluster {/,/}/s/name = "'"$old"'"/name = "'"$new"'"/' file
cluster {
  name = "Worker Nodes"
  owner = "Cavendish Laboratory"
  .....
  .....
}
module {
    name = "core_metrics"
}
    service {
    name = "ssh_check"
}
......
......
  • Focus on lines between cluster { and }. /cluster {/,/}/
  • Substitute new for old s/name = "'"$old"'"/name = "'"$new"'"/

Upvotes: 1

asf107
asf107

Reputation: 1146

Here's how I'd do it "in words":

1) Read each line

2) Whenever a line pattern-matches cluster {, set a boolean variable wasClusterLine = true

3) On the next line, if wasClusterLine is true, then do your name = reg-ex replace on the current line

4) set wasClusterLine = false, because you only want to do your reg-ex replace on the line immediately after cluster { .

Hope that helps! Here's a perlscript that should do what I've described above.

use strict;
my $wasClusterLine = 0;
while(<STDIN>) {
        chomp $_;

        if($wasClusterLine == 1) {
                $_ =~ s/name = .*/name = "Worker Nodes"/g;
        }
        $wasClusterLine = 0;

        if($_ =~ /cluster/) {
                $wasClusterLine = 1;
        }

        print "$_\n";
}

Upvotes: 1

Related Questions