Heuristic
Heuristic

Reputation: 169

Perl finding a file based off it's extension through all subdirectories

I have a segment of code that is working that finds all of the .txt files in a given directory, but I can't get it to look in the subdirectories.

I need my script to do two things

  1. scan through a folder and all of its subdirectories for a text file
  2. print out just the last segments of its path

For example, I have a directory structed

C:\abc\def\ghi\jkl\mnop.txt

I script that points to the path C:\abc\def\. It then goes through each of the subfolders and finds mnop.txt and any other text file that is in that folder.

It then prints out ghi\jkl\mnop.txt

I am using this, but it really only prints out the file name and if the file is currently in that directory.

opendir(Dir, $location) or die "Failure Will Robertson!";
@reports = grep(/\.txt$/,readdir(Dir));
foreach $reports(@reports)
{
    my $files = "$location/$reports";
    open (res,$files) or die "could not open $files";
    print "$files\n";
}

Upvotes: 5

Views: 18314

Answers (3)

Tk421
Tk421

Reputation: 6418

I do believe that this solution is more simple and easier to read. I hope it is helpful !

#!/usr/bin/perl

use File::Find::Rule;

my @files = File::Find::Rule->file()
                            ->name( '*.txt' )
                            ->in( '/path/to/my/folder/' );

for my $file (@files) {
    print "file: $file\n";
}

Upvotes: 7

wholerabbit
wholerabbit

Reputation: 11566

Much easier if you just use File::Find core module:

#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);

use File::Find;

my $Target = shift;

find(\&survey, @ARGV);

sub survey { 
    print "Found $File::Find::name\n" if ($_ eq $Target) 
}

First argument: pathless name of file to search for. All subsequent arguments are directories to check. File::Find searches recursively, so you only need to name the top of a tree, all subdirectories will automatically be searched as well.

$File::Find::name is the full pathname of the file, so you could subtract your $location from that if you want a relative path.

Upvotes: 2

Timothy Brown
Timothy Brown

Reputation: 2280

What about using File::Find?

#!/usr/bin/env perl

use warnings;
use strict;
use File::Find;

# for example let location be tmp
my $location="tmp";

sub find_txt {
    my $F = $File::Find::name;

    if ($F =~ /txt$/ ) {
        print "$F\n";
    }
}


find({ wanted => \&find_txt, no_chdir=>1}, $location);

Upvotes: 6

Related Questions