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

I have a text file whose data looks like the following,Now I am trying to do the following,currently my code is not working for step2.

For every line starting with "missing" on the input file below 1.replace "\" with "/" 2.replace $root_dir with $perforce_root_dir 3.Save the resulting perforce path in another text file "perforcefiles.txt"

INPUT FILE(p4diff.log) DATA:- missing E:\qdepot_automation\addfiles.txt same E:\qdepot_automation\AMSS\products\build\ms\files.data same E:\qdepot_automation\AMSS\products\build\ms\build.cmd missing E:\qdepot_automation\AMSS\products\build\textfiles.txt same E:\qdepot_automation\AMSS\products\build\ms\lib.min #!/usr/bin/perl -w use strict; use warnings; use Cwd; my $client_root="E:\\qdepot_automation"; my $perforce_root_dir="\/\/depot\/code"; my $input = <p4diff.log>; my $line; #my ($client_root,$clientroot); open(my $OUTPUT, '+>', "perforcefiles.txt") or die $!; open my $DATA, '<', $input or die "could not open '$input' $!"; while ($line = <$DATA>) { if ($line =~ /missing/) { $line =~s/\\/\//g; $line =~s/$client_root/$perforce_root_dir/g; ###This line is not wo +rking,basically am not able to replace client_root with perforce_root +_dir print "$line\n"; print $OUTPUT $line; } } close OUTPUT; OUTPUT:- E:\qdepot_automation>perl deletefiles.pl Name "main::OUTPUT" used only once: possible typo at deletefiles.pl li +ne 25. missing E:/qdepot_automation/addfiles.txt

Replies are listed 'Best First'.
Re: Not able to replace to directory paths
by GrandFather (Saint) on Mar 10, 2011 at 21:24 UTC

    When I run the code you supplied (using <DATA> and putting the input file contents in the __DATA__ section) it generates:

    Name "main::OUTPUT" used only once: possible typo at ... . missing E:/qdepot_automation/addfiles.txt Unrecognized escape \q passed through in regex; marked by <-- HERE in +m/E:\q <-- HERE depot_automation/ at ... . missing E:/qdepot_automation/AMSS/products/build/textfiles.txt

    which is different than the result you report. Your reported result is obtained by not using strictures! If you actually used strictures as you are pretending to you'd have been further on toward an answer to your problem: you are using \ instead of / in your match string. You should probably also meta quote the match string in case a . or other interesting character is part of the path you are matching. Consider:

    use strict; use warnings; my $client_root = "E:/qdepot_automation"; my $perforce_root_dir = "//depot/code"; my $line; while ($line = <DATA>) { if ($line =~ /missing/) { $line =~ s/\\/\//g; $line =~ s/\Q$client_root\E/$perforce_root_dir/g; print "$line\n"; } } __DATA__ missing E:\qdepot_automation\addfiles.txt same E:\qdepot_automation\AMSS\products\build\ms\files.data same E:\qdepot_automation\AMSS\products\build\ms\build.cmd missing E:\qdepot_automation\AMSS\products\build\textfiles.txt same E:\qdepot_automation\AMSS\products\build\ms\lib.min

    prints:

    missing //depot/code/addfiles.txt missing //depot/code/AMSS/products/build/textfiles.txt
    True laziness is hard work

      I have a interesting problem now,the below code dumps "$stdout" output of the $cmd command run to "p4diff.log",what I noticed is it's not entering the while loop if I do this where as if I use a pre-existing p4diff.log without generating through the program it enters the program,any idea what could be wrong in the below code

      $cmd = [ (qw(p4 diff -f -sl), $options{v}) ]; run3($cmd, \$stdin, \$stdout, \$stderr); #print "\n$stderr\n"; #Output the diff to p4diff.log open(my $P4DIFF, '+>', "p4diff.log") or die $!; print $P4DIFF $stdout; $input = <p4diff.log>; #Open teh p4diff.log to get the missing files and output to dele +tefiles.txt open(my $OUTPUT, '+>', "deletefiles.txt") or die $!; open my $DATA, '<', $input or die "could not open '$input' $!"; while ($line = <$DATA>) { print "IN WHILE LOOP\n";#not printing if ($line =~ /missing/) { $line =~s/\\/\//g; $line =~s/\Q$client_root\E/$perforce_root_dir/g; print "$line\n"; print $OUTPUT $line; } } close $OUTPUT;

        Maybe you should close $P4DIFF before you open the associated file?

        Depending on how much you've written, the IO buffer (size 4k) might not have been flushed yet, so the file behind $DATA could be empty.  In other words, you'd get EOF with the loop quitting right away...

        This doesn't print anything (i.e. while loop not entered):

        open(my $P4DIFF, '+>', "p4diff.log") or die $!; print $P4DIFF "foo\n" x 3; # close $P4DIFF; my $input = "p4diff.log"; open my $DATA, '<', $input or die "could not open '$input' $!"; while (my $line = <$DATA>) { print ">> $line"; }

        while if you uncomment the close, you'd get:

        >> foo >> foo >> foo

        What does $input contain? What do you expect it to contain? What does the file of the name in $input contain? Why are you not using strictures?

        True laziness is hard work
Re: Not able to replace to directory paths
by Eliya (Vicar) on Mar 10, 2011 at 21:22 UTC

    In addition to what the Anonymous Monk said, you need to reverse the order of the substitutions, because if you do $line =~s/\\/\//g; before you look for E:\..., you won't find the backslash any longer...

    Also, it should be close $OUTPUT (note the $) to get rid of the "used only once" warning.

      Actually the normalisation substitution ($line =~s/\\/\//g;) should be first so that either form of path separator can be used for input and successfully matched later on against a normalised match string using / instead of \.

      True laziness is hard work
Re: Not able to replace to directory paths
by ~~David~~ (Hermit) on Mar 10, 2011 at 21:16 UTC
    Line 25 needs to be close $OUTPUT.
    I also had some errors on your line #5. I switched to my $client_root='E:/qdepot_automation';
Re: Not able to replace to directory paths
by Anonymous Monk on Mar 10, 2011 at 21:11 UTC