Solved

Script to read files in subfolders

Posted on 2001-09-17
4
368 Views
Last Modified: 2012-05-04
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
Comment
Question by:zoobird
  • 3
4 Comments
 
LVL 5

Expert Comment

by:PC_User321
ID: 6490336
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
 

Author Comment

by:zoobird
ID: 6490554
I have not tried your script yet but do you have any idea why my code is failing?
0
 
LVL 5

Expert Comment

by:PC_User321
ID: 6495075
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
 
LVL 5

Accepted Solution

by:
PC_User321 earned 50 total points
ID: 6495733
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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question