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

I need to verify that a bunch of files exist and are not empty. The basic location is '/strek/$race/logs/rlog0-4.sr.html'

This is what I have so far, which is failing:
my $ldir = '/strek'; my @races = undef; opendir my $dh, $ldir or die "$0: opendir: $!"; while (defined(my $name = readdir $dh)) { next unless {-d "$ldir/$name"}; push (@races, $name); } while (my $race = <@races>) { for my $i (0..4) { if ( -s '/strek/$race/logs/rlog$i.sr.html' ) { next; } else { print "/strek/$race/logs/rlog$i.sr.html either does not exist + or is 0 bytes!\n"; } } }

This is executing the print statement every time, including for files that should be 'true'. Can anyone help with this?

Replies are listed 'Best First'.
Re: file check loop
by toolic (Bishop) on Jul 30, 2013 at 15:13 UTC
Re: file check loop
by Anonymous Monk on Jul 30, 2013 at 15:22 UTC

    You've a typo in the line:

    if ( -s '/strek/$race/logs/rlog$i.sr.html' ) {

    Since you use single quotes $race and $i are not substituted by their value. Just try:

    if ( -s "/strek/$race/logs/rlog$i.sr.html" ) {

      My anonymous brother is quite right. You can avoid this sort of problem (where by you test one thing but actually report another) by using a variable name for both. eg.

      my $file = "/strek/$race/logs/rlog$i.sr.html"; if ( -s $file ) { next; } else { print "$file either does not exist or is 0 bytes!\n"; }

      Other things you could do include making more use of the $ldir variable and rolling the second loop into the first.

      #!/usr/bin/perl use strict; use warnings; my $ldir = '/strek'; my @races = undef; opendir my $dh, $ldir or die "$0: opendir: $!"; while (defined(my $name = readdir $dh)) { next unless -d "$ldir/$name"; push (@races, $name); for my $i (0..4) { my $file = "$ldir/$name/logs/rlog$i.sr.html"; if ( -s $file ) { next; } else { print "$file either does not exist or is 0 bytes!\n"; } } } # Now do something useful with @races here
Re: file check loop
by marinersk (Priest) on Jul 30, 2013 at 17:06 UTC
    Without any further examination, I would change the following line thusly:
    while (my $race = <@races>) {
    to
    foreach my $race (@races) {
Re: file check loop
by mtmcc (Hermit) on Jul 30, 2013 at 15:24 UTC
    Does this work?:

    #!/usr/bin/perl use strict; use warnings; my $ldir = '/strek'; my @races = undef; opendir my $dh, $ldir or die "$0: opendir: $!"; while (defined(my $name = readdir $dh)) { next unless {-d "$ldir/$name"}; push (@races, $name); } for (@races) { for my $i (0..4) { if ( -s "/strek/$_/logs/rlog$i.sr.html" ) { } else { print "/strek/$_/logs/rlog$i.sr.html either does not exist or + is 0 bytes!\n"; } } }

      You don't want to initialize your array like so: my @races = undef; because like so, you already have an element in the array. Which is not what you want to do.
      You can simply do my @races = (); OR more better my @races; just like toolic posted above.

      If you tell me, I'll forget.
      If you show me, I'll remember.
      if you involve me, I'll understand.
      --- Author unknown to me

      Well, does this work?

      >perl -wMstrict -le "opendir my $dh, '.' or die qq{opening .: $!}; while (defined(my $dname = readdir $dh)) { next unless { -d $dname }; print qq{dir '$dname'}; } " Odd number of elements in anonymous hash at -e line 1. dir '.' Odd number of elements in anonymous hash at -e line 1. dir '..' Odd number of elements in anonymous hash at -e line 1. dir '10001fr.equ' Odd number of elements in anonymous hash at -e line 1. dir '10002fr.equ' ... Odd number of elements in anonymous hash at -e line 1. dir 'Wrap_Simple.pm' Odd number of elements in anonymous hash at -e line 1. dir 'Wrap_Simple.pm.bak' Odd number of elements in anonymous hash at -e line 1. dir 'xxxx'
Re: file check loop
by Cristoforo (Curate) on Jul 30, 2013 at 16:59 UTC
    This might be a solution
    for my $dir (glob "/strek/*/logs") { for my $i (0 .. 4) { print "$dir/rlog$i.sr.html either does not exist or is 0 bytes +!\n" unless -s "$dir/rlog$i.sr.html"; } }
    I don't think glob can be used this way, (with an array to be globbed).
    while (my $race = <@races>)
    for my $race (@races)
Re: file check loop
by Laurent_R (Canon) on Jul 30, 2013 at 21:32 UTC

    You have been given a lot of useful comments on various faulty details in your code, but I was going to suggest the same thing as Cristoforo: I think that you should take a look at the glob function. It is often much more practical in a number of respects than opendir/readdir.