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

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

final result would be

file1:- 12 4947000219 20140924105028

file2:- 12 4947000220 20140924105228

file3:- 12 4947000221 20140924105428

Done the changes in code,no error but not getting desire result

#!/usr/bin/perl -w use File::Copy; use 5.010; # For autodie and regex \K use Time::Piece; use Time::Seconds qw/ ONE_MINUTE /; use constant DATE_FORMAT => '%Y%m%d%H%M%S'; my $source_file = "KOH_1026.udr"; my $lines; my $tp; for my $i (1 .. 3) { copy($source_file, sprintf("KOH_1026%02d.udr", $i)) or die "Copy faile +d: $!"; open my $input_file, '<', $source_file; my @lines = <$input_file>; close $input_file; foreach (@lines) { $n++; $lines[0] =~ s~/(4947000219)/$1+$n/~e; $lines[1] =~ s{:20140924105028(\d+)}{ $tp = Time::Piece->strptime($1, DATE_FORMAT); ($tp + ONE_MINUTE * 2 * $n)->strftime(DATE_FORMAT); }e; open my $output_file, '>',$source_file; print $output_file @lines; close $output_file; } }

Error Message

String found where operator expected at ./prog.pl line 33, near "$lines1 =~ 's{:20140924105028(\d+)}'" (Missing operator before 's{:20140924105028(\d+)}'?) syntax error at ./prog.pl line 33, near "$lines1 =~ 's{:20140924105028(\d+)}'" Can't use global $1 in "my" at ./UDR_Tool.pl line 34, near "($1" syntax error at ./prog.pl line 41, near "}" Bareword "e" not allowed while "strict subs" in use at ./prog.pl line 36.

Monks need your help to resolve the issue

  • Comment on Dera Monks, Have create multiple file from one file now I want to match a pattern in each file at the same time do the replacement with adding one to the match pattern.
  • Download Code
  • Watch for: Direct replies / Any replies

Replies are listed 'Best First'.
Re: Dear Monks, Have created multiple files from one file ...
by Athanasius (Archbishop) on Dec 31, 2014 at 17:03 UTC

    Hello hemantjsr,

    Like Laurent_R, I don’t understand what you are trying to do. However, in the code posted I do notice a major problem in the use of variables. First, in the lines:

    foreach my $line (@lines) { $line = $_;

    $_ is undefined, so you are immediately deleting the contents of $line and replacing them with undef. (And the line would accomplish nothing, anyway, even if $_ did contain the next element of @lines, as that element has already been stored in $line via the foreach statement.)

    Second, in the lines:

    $line[0] =~ s~/4947000219/\K(4947000210+)~$1+$n~e; $line[1] =~ s{:20140924105028\K(\d+)}{

    you are accessing the first and second elements of the array @line. But as this array has never been declared, the substitutions have nothing to work on. Please note that the array @line is an entirely different variable from the scalar $line. (I notice that you do declare a variable my $lines, but that variable is never used.) If you begin your script with:

    use strict;

    this will provide some (but not all) of the help you need to identify errors of this kind. See also Perl variable types and perldata.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Done the changes in code, although am not getting any error but interpolation not happeningg

        Maybe you should add some debugging prints to see whether $line[0] and $line[1] are actually getting their replacements?

        Maybe the input data does not match what you expect?

Re: Dera Monks, Have create multiple file from one file now I want to match a pattern in each file at the same time do the replacement with adding one to the match pattern.
by Laurent_R (Canon) on Dec 31, 2014 at 12:11 UTC
    And what is your question?

      If I'm not wrong the question is: how to do a global substitution of a pattern over several files replacing the pattern by $counter and also updating $counter as $counter+1 each time a substitution is done.

      I have some doubts about this lines

      ++$n; $lines[0] =~ s[/4947000219/\K(4947000210+)] [$1+$n]e;

      You search for a big number, then discard the first ten digits, capture next digits and replace it by $1+$n in an eval (e) context when $n is a counter. Ok.

      The use of \K here also confuses me a little. Can't see the point of doing this here when you aren't really picking up those digits

      when \K is reached Perl throws away everything that it has matched up to that point. It means that our replacement won’t affect anything before the \K, because Perl will have forgotten about it

      I wonder if you want to say $n++ or $n += 1 instead ++$n

        Yes Dera your understanding is correct. Could you please help me tell how to do substitution incrementally. As I try to do with \K which seems not working for me, done the changes $n++

        $lines[0] =~ s~/4947000219/\K(4947000210+)~$1+$n~e;

        Done some changes now $lines[0] working fine.. thanks for your help /K creating a problem.. But still issue with $line1

        $lines[0] =~ s~/(4947000219)/$1+$n/~e;

        Working fine

        $lines[1] =~ 's{:20140924105028(\d+)}'{ my $tp = Time::Piece->strptime($1, DATE_FORMAT); ($tp+ONE_MINUTE*2*$n)->strftime(DATE_FORMAT);
         }e;

        Error message

        String found where operator expected at ./prog.pl line 33, near "$lines1 =~ 's{:20140924105028(\d+)}'" (Missing operator before 's{:20140924105028(\d+)}'?) syntax error at ./prog.pl line 33, near "$lines1 =~ 's{:20140924105028(\d+)}'" Can't use global $1 in "my" at ./prog.pl line 34, near "($1" syntax error at ./prog.pl line 41, near "}" Bareword "e" not allowed while "strict subs" in use at ./prog.pl line 36.

        As m very new in perl you kind help would be highly appreciated.

      Hello Dera As I'm very new in Perl, created a code which will create multiple file with one file and each file have same value,this part is done.Now in second part want to replace matched pattern in each file with adding one to it.In output i want match a pattern 219 and add one to it and replace in file 2 (means in file2 value would be 220) and in file3 value would be 221 , same case with second value which is 20140924105028

      example file01 output

      12,219,20140924105028

      file02 output

      12,220,20140924105228

      file03 output

      12,221,20140924105428

      but with the given code m not able to do it.Kindly help in this regard.