user7875136
user7875136

Reputation:

Perl question. Need a way to replace two variables on the same line

I am trying to write a replace script in Perl, and I have it working halfway, but it seems that I cannot replace two strings in the same line.

I have a json file named foo.json that contains the following line: "title": "%CLIENT% Dashboard Web Map %WEBMAPENV%",

Now, I have a second file named env.txt that contains all the variables that I wish to use. In this file, there is an entry called: %WEBMAPENV%=(Test-Dev). My goal is to have PERL read the file env.txt, and replace BOTH "%CLIENT% and %WEBMAPENV% simultaneously.

Here is my code so far:

my $envFilePath = "$dirScripts/env/env.txt";

# Reading Firebase variables from Test environment file.
open($fh, "<", $envFilePath);

while (my $line=<$fh>) {
  if ($line eq "\n") {
    next;
  }

  if ($line =~ m/^(%\w+%)=/) {
    $cur_key = $1;

    $line =~ s/$cur_key=//;

    $replacements{$cur_key} = $line;
  } else {
    $replacements{$cur_key} .= $line;
  }
}

...

my $targetFilePath3 = "$dirHome/foo.json";

tie my @v_lines, 'Tie::File', $targetFilePath3, autochomp => 0 or die $!;

replaceEnvVars(@v_lines);

# Replace the environment variables as part of the setup.
sub replaceEnvVars {

for my $line (@_) {
  if ($line =~ m/(%\w+%)/) {
    my $key = $1;
    if (defined($replacements{$key})) {
      my $value = $replacements{$key};
      chomp $value;
      $line =~ s/$key/$value/g;
    }
  }
}
untie @_;
}

I am only able to substitute one variable per line, but I need to be able to handle 2.

Can any offer some help?

Derek

Upvotes: 1

Views: 89

Answers (1)

ikegami
ikegami

Reputation: 385867

You only check for one.

 if ($line =~ m/(%\w+%)/) { ... }

Solution:

# Clean up %replacements before using it.
chomp for values %replacements;

for my $line (@_) {
  $line =~ s{(%\w+%)}{ $replacements{$1} // $1 }eg;
}

By adding a loop inside of s/// (through the use of /g) rather than a loop around s///, this one doesn't mess up if the values contain %.

/e means the replacement will be run as Perl code.

// is the "defined-or" operator. It works like || but looks for defined rather than truth.

See the Perl Regex Tutorial for more.

Upvotes: 3

Related Questions