http://www.perlmonks.org?node_id=1054992

Harkers has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm completely new to PERL so sorry if this is a stupid question. What I want to happen is have text $oldstr replaced with $newstr and a counter (so $newstr text 1, 2, 3 for each instance of replacement) across a batch of files in a particular folder (although I'm only working on one file directly as yet). One of the problems I'm having is the counter is including the lines in between, so my replacement text is $newstr text 3, 9 11 etc. How do I get the counter to only add 1 when the $oldstr is found and replaced by the $newstr? any help much appreciated

use strict; open(FILE, "<test.xml") || die "File not found"; my @lines = <FILE>; close(FILE); my $oldstr = "core:para"; my $newstr = "core:para edpnum\-start\=\""; my @newlines; my $counter =0; foreach(@lines) { if ($oldstr =~ /core\:para/){ $counter = $counter +1; } $_ =~ s/$oldstr/$newstr$counter/g; push(@newlines,$_); } open(FILE, ">test.xml") || die "File not found"; print FILE @newlines; close(FILE);

Replies are listed 'Best First'.
Re: search and replace plus counter
by hippo (Bishop) on Sep 20, 2013 at 10:17 UTC

    Your problem is that $oldstr never changes so your test of it using if ($oldstr =~ /core\:para/) is always true. You want to test $_ against that pattern, not $oldstr.

    HTH

      Thank you - that works a treat
Re: search and replace plus counter
by hdb (Monsignor) on Sep 20, 2013 at 10:48 UTC

    The substitution operator returns the number of substitutions in scalar context, so you could write it like this:

    use strict; use warnings; my @strings = qw/ one two three /; my $counter = 0; for ( @strings ) { $counter += s/o/O/; # only add one if s/// is successful } print "$counter replacements\n"; print "@strings\n"; $counter = 0; for ( @strings ) { $counter += s/e/E/g; # add number of replacements } print "$counter replacements\n"; print "@strings\n";

    UPDATE: When you want to use the counter in your replacement string, then adding one should do the trick, not forgetting to remove it later:

    use strict; use warnings; my @strings = qw/ one two three four /; my $counter = 1; for ( @strings ) { $counter += s/o/O$counter/; # only add one if s/// is successful } $counter--; print "$counter replacements\n"; print "@strings\n";
Re: search and replace plus counter
by Anonymous Monk on Sep 20, 2013 at 10:28 UTC