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

Hello dear Monks,

I have written a code that makes some operations in several directories then gathers the results in a file

The problem is that no error is indicated but the outfile file is void. Could you check ?, thanks.

Here is a simplified version so if there are some errors, there should be minor. I believe that the problem may lie with the line where I call the child script.

use strict; BEGIN { open(STDERR, ">stderr.log") or die "Failed to open log file"; } my $slot_outfile = "results.csv"; open my $SLOT_OUTFILE, q{>}, $slot_outfile or die; my @REG_list = qw{Regulation_AZT Regulation_IOP Regulation_AERTC}; chdir(".."); chdir("ALL_WEEKS"); my $reg; my $week = "W36"; foreach $reg (@REG_list){ chdir("semaine_${week}/${reg}") or die "Can't go into the director +y $reg!"; my @SLOTS = glob("slot_list*.out"); my @SLOTS_01 = grep /(\w+).(\d\d).(01).(\w+).out/, @SLOTS; my $slot_file = $SLOTS_01[0]; my $cmd = "perl ../../../WP4_utility_analysis/WP4_utility.pl $slot +_file $SLOT_OUTFILE"; system($cmd); chdir("../.."); }

and the child program WP4_utility.pl is

use strict; BEGIN { open(STDERR, ">stderr2.log") or die "Failed to open log file"; } my $slot_file = $ARGV[0]; my $OUFTILE = $ARGV[1]; open my $SLOT_INFILE, q{<}, $slot_file; my %hash; while (my $line = <$SLOT_INFILE>) { my @Elements = split /;/, $line; $hash{$Elements[0]} = $Elements[1]; } my @Keys = keys %hash; my $key; foreach $key(@Keys){ print $OUTFILE "$key;$hash{$key}\n"; } close STDERR;

Replies are listed 'Best First'.
Re: results printing error
by apl (Monsignor) on Apr 15, 2008 at 13:26 UTC
    Just shooting from the hip, I think you want to replace

    my $cmd = "perl ../../../WP4_utility_analysis/WP4_utility.pl $slot_fil +e $SLOT_OUTFILE";

    with

    my $cmd = "perl ../../../WP4_utility_analysis/WP4_utility.pl $slot_fil +e >$slot_outfile"

    Then you need to have your second script print to STDOUT rather than $OUTFILE.

Re: results printing error
by ww (Archbishop) on Apr 15, 2008 at 13:30 UTC

    I wonder if your problem might be IN WP4_utility.pl at 7 and 8:

    my $ligne_number=0; my $analyse_file=0;

    which are never seen again.

    But, re your surmise about the call in the parent, you have an inexplicable (to me, anyway) chdir in the last line you've supplied. Did you perhaps try to create a minimal test case, and exclude something important? And have you considered turning the child into a module to enable use of the child without resort to Windows' CMD?

      Thanks a lot ww

      But the two lines you mention are optional

      the chdir("../..") at the end of the parent script is because I have previously entered into two directories and I wish to go back to the point where I can change of directories and go in the directory of the next $reg

Re: results printing error
by moritz (Cardinal) on Apr 15, 2008 at 13:27 UTC
    You don't check the return value of system. Do that.
Re: results printing error
by olus (Curate) on Apr 15, 2008 at 13:31 UTC

    Maybe you should try to pass he name of the file where you are to write the results instead of passing the opened filehandle. You should then open the file in the WP4_utility script.

    Update: And, why not do it all in only one script with all the functionality of the utility in one function?

      Thanks a lot olus

      But if I do that, each time a file is opened, the results will erase the precedent ones. Unless I use >> or am I mistaken ?

      update

      The main reason I used a child script was to test it directly on a file

      I also tried to use a function with sub but I do not know how to say that the return I would like is a print on file

        Is this (an outrageously simplified version of ) what you want?

        #!/usr/bin/perl use strict; use warnings; print STDOUT sub1(); sub sub1 { my $string = "foo bar \n"; $string .= $string; }

        Season to taste with an appropriate filehandle and sub.
          "taste" may improve with a hearty helping of perldoc...

Re: results printing error
by oko1 (Deacon) on Apr 15, 2008 at 16:27 UTC

    One of the first things you usually want to consider, when looking a task to be done, is "what part of it can I automate?" With Perl, that often means looking for a module - and when you want to walk directories, File::Find should be the first thing that comes to mind.

    There are also a number of problems in your script - trying to pass a filehandle (instead of a filename) as an argument to the script, lots of temporary variables, invoking 'system' unnecessarily and failing to check its return - as a number of other people here have pointed out. I'd usually correct those and explain how to do them better, but this isn't just a case of a poorly-written function or two - your approach is the largest problem. I'm just going to take the lazy way out and provide the solution, while hoping that you'll consider those problems from a new perspective.

    Since I don't have your data set, and since much of your code is redundant and difficult to read, I'm going to take a few liberties and guess at what you're trying to do in places. You're probably going to need to correct a few things.

    #!/usr/bin/perl -w use strict; use File::Find; ### User-modifiable variables ### my $reg = 'AZT,IOP,AERTC'; my $week = 'W36'; ### User-modifiable variables ### # Get the dirlist for File::Find my @dirs = glob "semaine_$week/Regulation_{$reg}"; # The 'find' subroutine comes from 'File::Find' find(\&process, @dirs); my %seen; sub process { # Skip if we've already processed the file in this directory next if $seen{$File::Find::dir}; # Skip unless the file matches the spec next unless /^slot_list\w*.\d\d\.01\.\w+\.out$/; # We've found the file that we want; now, we'll process it open Out, ">results.csv" or die "results.csv: $!\n"; open Fh, $_ or die "$_: $!\n"; while (my $line = <Fh>){ chomp $line; my ($key, $val) = split /;/, $line; print Out "$key;$val\n"; } close Fh; close Out; # Mark directory as 'processed' $seen{$File::Find::dir}++; }

    Update: Corrected the regex. I'd already fixed it in the script, but still had the old copy in the buffer...

    
    -- 
    Human history becomes more and more a race between education and catastrophe. -- HG Wells