• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 377
  • Last Modified:

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.
0
zoobird
Asked:
zoobird
  • 3
1 Solution
 
PC_User321Commented:
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
     }
}

0
 
zoobirdAuthor Commented:
I have not tried your script yet but do you have any idea why my code is failing?
0
 
PC_User321Commented:
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.)

   
0
 
PC_User321Commented:
I tried your code on Win2000 with this line added:
    open(L, ">log.txt") or die "Cannot open log.txt: $!\n";
and it worked fine, with and without the
    parse("$name");
line.  The program looked in directories with purely numeric names and in directories with non-numeric names.


Note that in my code the 'wanted' subroutine processes _directories_ as well as files.  Add an 'unless (-d)' test if you want only files.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now