views:

69

answers:

4

Hello all,

i'm trying to write a script which would process certain files. The data are organized like this: there is a folder (let's call it X) where my script will be placed. In this same folder there is a subfolder called 'data'. This contains several more subfolders with various names and each of these contains many files (no other subfolders, just files). I need to process all files in a subfolder (more specifically, run a function on each file) and then merge the results for all files in the subfolder, so for each folder there is one result (no matter how many files it contains).

The problem is, i'm not able to get to the files so i could run my function on them. What i have now is this:

$dirname = "data";

opendir ( DIR, $dirname ) || die "Error in opening dir $dirname\n";

while( ($dirname2 = readdir(DIR)) ) 
{
    next if $dirname2 eq ".";
    next if $dirname2 eq "..";

    opendir ( DIR2, $dirname2 ) || die "Error in opening dir $dirname2\n";

    while( ($file = readdir(DIR2)) ) 
    {
        next if $file eq ".";
        next if $file eq "..";

        print( "file:$file\n" );
    }

    closedir(DIR2);

}
closedir(DIR);

It always fails with the message "Error in opening dir alex". 'alex' happens to be the first directory in the data directory. My question is - where is the problem? Is this even the correct way how to achieve what i'm trying to do? I'm also worried that this my fail if there is a file also in the data folder, since i cannot open it with opendir, or can I?

PS: sorry for that horrible Perl code - i'm still trying to learn this language.

Thanks, Peter

+1  A: 

you can use File::Find to do find files nested directories

ghostdog74
+1  A: 

You can try File::Path - Create or remove directory trees

As i am running your program, i think you have to specify your full path while opening a directory ie.,

opendir ( DIR2, $dirname.\\.$dirname2 ) || die "Error in opening dir $dirname2\n"; #running code on windows

It will work, try it.

Nikhil Jain
That was the crucial mistake. Thank you!
PeterK
+1  A: 

Are you sure that inside folder exist only folders? Add additional check:

next if !(-d $dirname2);
Michael Pakhantsov
Thanks, this will help.
PeterK
A: 

Here is a slightly cleaned up version of what was posted in the question.

use strict;
use warnings;
use autodie;
use File::Spec::Functions qw'catdir';

my $dirname = "data";

{
    opendir my $dir, $dirname;

    while( my $dirname2 = readdir(DIR) ){
        next if $dirname2 eq ".";
        next if $dirname2 eq "..";

        $dirname2 = catdir( $dir, $dirname2 );
        next unless -d $dirname2;
        opendir my $dir2, $dirname2;

        while( my $file = readdir($dir2) ) 
        {
            next if $file eq ".";
            next if $file eq "..";

            $file = catdir($dirname2,$file);
            if( -f $file ){
              print( "file:$file\n" );
            }
        }
        # $dir2 automatically closes here
    }
    # $dir automatically closes here
}

If you are going to run it on Perl versions earlier than 5.12.0 you should wrap the while loop's conditional with defined().

    while( my $dirname2 = readdir(DIR) ){
    while( defined( my $dirname2 = readdir(DIR) ) ){
Brad Gilbert