Link to home
Start Free TrialLog in
Avatar of zoobird
zoobird

asked on

Script to read files in subfolders

I have a perl script that looks into a certain directory with hundreds of subfolders each having a number of files. The names of these subfolders can be one of the following format:

5 digits - e.g. 00102, 39484
3 characters - e.g. Abc, Def

I have to read each of these directories and look for a certain file. My problem is that it only seems to read those of the 5 digit format when I call a certain function.

Here is part of my code:

#! /usr/bin/perl -w

use Cwd; # module for finding the current working directory

## A few globals
my $DIR = "test_data";

# Today by default or whatever date is passed. Don't forget leading zeros.
my ($day, $month) = (localtime())[3,4];
$month += 1;
my $today = $ARGV[0] || sprintf("%02d%02d", $month, $day);

#
## Main thing
#
scandir($DIR);

#
## Subroutine to allow filesystem to be traversed
#

sub scandir {
     my ($workdir) = shift;

     my $startdir = cwd();

     chdir($workdir) or die "Cannot chdir to $workdir: $!\n";
     opendir(DIR, ".") or die "Cannot open $workdir for reading: $!\n";
     my @names = readdir(DIR) or die "Cannot read $DIR: $!\n";

     closedir(DIR);
     
     foreach my $name (@names) {
          next if ($name eq ".");
          next if ($name eq "..");
     
          if (-d $name) {
               scandir("$workdir\\$name");
               next;
          }
          if ($name =~ m/t\w+$today\.dat/) {
               print "Parsing: $workdir\\$name\n";
               print L "Parsing: $workdir\\$name\n";
               #parse("$name");
                   
          }
     }
     chdir($startdir) or die "Unable to chdir to $startdir: $!\n";
}


#
## Subroutine to parse the *.dat file and output to a *.txt file
#

sub parse {    
     my $FILENAME = shift;    
       
        print L "Filename: $FILENAME\n";
}




Note the commented line "parse("$name")". If I comment this out, the script traverses through all the folders. If I call the parse procedure, it only goes through the digit subfolders.

Any thoughts? I'm new to Perl, and I'm not sure if this question is easy or difficult. If the points need to be increased, I am willing to do so.
Avatar of PC_User321
PC_User321

Hi.  Perl has a useful function called File::Find that traverses through subdirectories.
Try this code, changed to suit your needs:

use File::Find;

## A few globals
my $DIR = "test_data";

# Today by default or whatever date is passed. Don't forget leading zeros.
my ($day, $month) = (localtime())[3,4];
$month += 1;
my $today = $ARGV[0] || sprintf("%02d%02d", $month, $day);

#
## Main thing
#
find(\&wanted, $DIR);

#
## Subroutine to handle each file found under all directories under $DIR
#

sub wanted {
    my $name = $_;
    print "Processing file $name in directory $File::Find::dir -- =  $File::Find::name\n";
    if ($name =~ m/t\w+$today\.dat/) {
        # Do things here
     }
}

Avatar of zoobird

ASKER

I have not tried your script yet but do you have any idea why my code is failing?
I have not tried to run your code but it looks OK except that:

You should change "Cannot read $DIR: $!\n"
to "Cannot read $workdir: $!\n"

and you need to open the file handle 'L'.  (Perhaps you do that but have not shown it in the code sample.)

   
ASKER CERTIFIED SOLUTION
Avatar of PC_User321
PC_User321

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial