views:

258

answers:

2

I am struggling with a method of walking a directory tree to check existence of a file in multiple directories. I am using Perl and I only have the ability to use File::Find as I am unable to install any other modules for this.

Here's the layout of the file system I want to traverse:

Cars/Honda/Civic/Setup/config.txt
Cars/Honda/Pathfinder/Setup/config.txt
Cars/Toyota/Corolla/Setup/config.txt
Cars/Toyota/Avalon/Setup/

Note that the last Setup folder is missing a config.txt file.

Edit: also, in each of the Setup folders there are a number of other files as well that vary from Setup folder to Setup folder. There really isn't any single file to search against to get into the Setup folder itself.

So you can see that the file path stays the same except for the make and model folders. I want to find all of the Setup folders and then check to see if there is a config.txt file in that folder.

At first I was using the following code with File::Find

my $dir = '/test/Cars/';
find(\&find_config, $dir);

sub find_config {
    # find all Setup folders from the given top level dir
    if ($File::Find::dir =~ m/Setup/) {
       # create the file path of config.txt whether it exists or not, well check in the next line 
       $config_filepath = $File::Find::dir . "/config.txt";
       # check existence of file; further processing
        ...
   }
}

You can obviously see the flaw in trying to use $File::Find::dir =~ m/Setup/ since it will return a hit for every single file in the Setup folder. Is there any way to use a -d or some sort of directory check rather than a file check? The config.txt is not always in the folder (I will need to create it if it doesn't exist) so I can't really use something like return unless ($_ =~ m/config\.txt/) since I don't know if it's there or not.

I'm trying to find a way to use something like return unless ( <is a directory> and <the directory has a regex match of m/Setup/>).

Maybe File::Find is not the right method for something like this but I've been searching around for a while now without any good leads on working with directory names rather than file names.

+4  A: 

File::Find finds directory names, too. You want to check for when $_ eq 'Setup' (note: eq, not your regular expression, which would also match XXXSetupXXX), and then see if there's a config.txt file in the directory ( -f "$File::Find::name/config.txt" ). If you want to avoid complaining about files named Setup, check that the found 'Setup' is a directory with -d.

ysth
@brian d foy: thanks
ysth
A: 

I'm trying to find a way to use something like return unless ( <is a directory> and <the directory has a regex match of m/Setup/>).

use File::Spec::Functions qw( catfile );

my $dir = '/test/Cars/';

find(\&find_config, $dir);

sub find_config {
    return unless $_ eq 'Setup' and -d $File::Find::name;
    my $config_filepath = catfile $File::Find::name => 'config.txt';
    # check for existence etc

}
Sinan Ünür
Thank you very much. ysth put me on the right path and you pretty much laid it all out.
seano