Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Using File::Find

by Dr Manhattan (Beadle)
on Feb 28, 2013 at 08:12 UTC ( #1021015=perlquestion: print w/replies, xml ) Need Help??
Dr Manhattan has asked for the wisdom of the Perl Monks concerning the following question:

Hi all

I want to search through my working directory and place all the text files with certain extensions (for example, all files ending with hp.txt) into a hash. I know I have to use File::Find, but I am new to using Perl and I can't figure out with the documentation how it works precisely.

Any help would be appreciated

Replies are listed 'Best First'.
Re: Using File::Find
by tmharish (Friar) on Feb 28, 2013 at 08:24 UTC

    find ( thats exported by File::Find ) requires you to define a function that will be used to pick files that you are want. Basic usage like so:

    use strict ; use warnings ; use File::Find; use Data::Dump; my $dir = shift || die "Dir name missing as argument\n"; my @files = (); find( \&wanted, "$dir" ); dd( \@files ) ; exit() ; sub wanted() { push @files, $File::Find::name if(/\.txt$/i); # .txt or whatever. }


      Another option, and possibly a simpler one for someone new to perl is to use File::Find::Rule. The example below searches through the current directory and its subdirectories, for all files with a .pl extension.

      Note that the result is stored in an array, not a hash. The result can be stored in a hash if the user needs to, but the key/value construct would need to be understood eg, is the key the path, and the value the file name, or is the key the full file name and the value the size of the file (or other attributes) etc....

      use strict; use warnings; use autodie; use File::Find::Rule; my @txt_files = File::Find::Rule ->file ->name('*.pl') ->in('./'); foreach (@txt_files) { print "$_\n"; }

      I hope this helps


      Thank you for the reply. I tried this:

      #!/usr/bin/perl -w use strict; use warnings; use File::Find; use Cwd; my $dir = getcwd; my %hashTS; find(&wantedTS, "$dir"); sub wantedTS() { if ($File::Find::name =~ /(.*)(\.ts)(\.txt)$/) { $hashTS{$File::Find::name}++; } }

      to place text files ending with .ts.txt into my hash, but it doesn't work because "Use of uninitialized value $File::Find::name"

        You're missing a backslash...

        find(\&wantedTS, "$dir");
        package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: Using File::Find
by daxim (Chaplain) on Feb 28, 2013 at 08:57 UTC
    File::Find has the worst interface of all finding modules. I recommend Path::Iterator::Rule instead.
    use Path::Iterator::Rule qw(); use Path::Tiny qw(path); my %files = map { $_ => path($_)->basename } Path::Iterator::Rule->new ->name(qr/hp[.]txt$/) # regex of file name ->all('.'); # starting in the current directory
Re: Using File::Find
by flexvault (Monsignor) on Feb 28, 2013 at 09:45 UTC

    Dr Manhattan,

    What's wrong with using 'glob'?

    perl -E '%h=glob("*hp.txt");say join("\n",%h);'
    you probably want to use a 'foreach' with 'keys' and maybe 'sort' to do something with the hash!

    But that's an easy way to work with your current directory.

    Good Luck...Ed

    "Well done is better than well said." - Benjamin Franklin

Re: Using File::Find
by reisinge (Friar) on Feb 28, 2013 at 11:53 UTC

    You might want to check Beginners guide to File::Find and/or my notes on File::Find.

    We are what we repeatedly do. Excellence, then, is not an act but a habit. -- Will Durant (Aristotle)

Re: Using File::Find
by Anonymous Monk on Feb 28, 2013 at 15:49 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1021015]
Approved by tmharish
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (8)
As of 2017-03-30 17:29 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (362 votes). Check out past polls.