Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

How do I read all files in a directory recursively?

by Anonymous Monk
on Mar 04, 2000 at 00:28 UTC ( #4827=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a group of files in the same directory, for each of I want to read the file and do the same processing. How do I read the files recursively? Thanks.
  • Comment on How do I read all files in a directory recursively?

Replies are listed 'Best First'.
RE: How do I read all files in a directory recursively?
by setantae (Scribe) on Mar 04, 2000 at 05:05 UTC
Re: How do I read all files in a directory recursively?
by plaid (Chaplain) on Mar 04, 2000 at 01:28 UTC
    The easiest way I can see to do it (assuming that you're running under a Unix variant) is to write a perl program that opens up $ARGV[0] as a file and does appropriate processing on it, then from your command line,
    find /path-to-files -exec /path-to-program {} \;
    This lets the find program take care of providing all the recursive paths. Call me a blasphemer if you want, but I think the find command is much easier to use than File::Find, and will be much easier to change in the future should you need to add flags to the find. Of course, then there's the issue of the reduced efficiency of launching multiple copies of the perl interpreter, which if you have many files could be an issue. It probably doesn't make much of a difference either way, I just thought I'd provide an additional viewpoint.
RE: How do I read all files in a directory recursively?
by Anonymous Monk on Mar 04, 2000 at 03:34 UTC
    I just wrote a program that toes exactly what you want to do. First I opendir() the directory then I readdir() the directory into an array. Finally I used foreach $file (@files) to process each file at a time

    The file I created scans a directory for mp3's and extracts their running time using MPEG::MP3Info

    It doesn't recurse subdirectories but that shouldn't be too hard to impliment by checking file attributes for the directory value. (at least in Win32) <code> #!c:\perl\bin\perl.exe use MPEG::MP3Info; my $file; my $out = '>>playlist.txt'; open (OUTFILE, $out); # replace with the directory containing the fines you want # does not recurse subdirectries $directory = "D:\\"; opendir (DIRECTORY, $directory); #read the file names into an array @files = readdir(DIRECTORY); #extract data from each file foreach $file (@files) { #is the file an mp3 if ($file =~ /.mp3/) { #extract info from mp3 using MPEG::MP3Info my $info = get_mp3info("$directory$file"); #get minutes and seconds my $minutes = $info->{MM}; my $seconds = $info->{SS}; #if seconds = 0 to 9 if (($seconds =~ tr/0-9/0-9/) == 1) { #set seconds = 00 to 09 so they print correctly $seconds = join ("", "0", $seconds); } #remove .mp3 extention from file name and print along with time
Re: How do I read all files in a directory recursively?
by Anonymous Monk on Mar 04, 2000 at 03:40 UTC
    Don't mind if I chip in myself. (plaid's approach doesn't take into account the possibility of a non-UNIX platform...)
    sub process_file { open F, shift; # stuff with F... close F; } sub recurse_dir { opendir D, shift; while (readdir D) { process_file ($_) if -f; recurse_dir ($_) if -d; } closedir D; } recurse_dir ($ARGV[0]);
    Two comments: first, I'm not sure if that's what the OP wanted at all. It's a rather useful idiom nonetheless. Second, this would have been a much more elegant solution had I made recurse_dir receive a subref and return a closure that recursively applied this subref to each file (as one would do in Scheme, e.g.). Unfortunately, this causes serious scope issues, especially if one chooses to use strict;

      Actually, this misses one small but important point. The code contains:

      recurse_dir ($_) if -d;

      This runs into problems when you see the directories "." and "..", so you need to do something more like:

      while (readdir D) { if (-d) { recurse_dir($_) unless ($_ eq '.' or $_ eq '..') } else { process_file($_) if -f } }
      One minor problem with the above code.. The opendir command is done relative to the current directory. If you were to opendir('dir1'), you would be looking in pwd/dir1. If you then found a directory inside of dir1 named dir2, an opendir('dir2') would look for pwd/dir2, which is not the desired result. To get the recursion right, the recurse_dir would have to look something like
      sub recurse_dir { my $dir = shift(); opendir D, $dir; while (readdir D) { process_file ($dir/$_) if -f $dir/$_; recurse_dir ($dir/$_) if -d _; } closedir D; }
      Either that, or the recurse_dir function could chdir in to each directory and chdir .. after the while loop.
RE: How do I read all files in a directory recursively?
by vroom (Pope) on Mar 04, 2000 at 00:44 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://4827]
Approved by root
[marioroy]: CORE::wait works well eventhough multiple instances or classes using Hobo::Manager.
[Corion]: marioroy: I'm not sure what the normal use for the PID is in P:FM, but I guess that most programs just ignore or log it
[Corion]: Oh, yes, programs could call wait $pid, but if your $pid is an object, then you could add a ->wait method to it and wait $pid would call that automatically "thanks" to indirect object notation
[marioroy]: Just documentation edits is all that remains. Hobo::Simple provides foreach and forseq with identifier capability -- all transparently supporting array, hash, file handle, and seq 1 .. N.
[marioroy]: Corion Regarding PID, that's great. So will leave it so compatible with MCE::Hobo. e.g. ->create returns a Hobo object. Folks can get ->pid from it. So, that's not a problem.
[choroba]: ad readdir: 5.12 needed
[marioroy]: CORE::wait can block if another process reaps a worker from another class. MCE::Hobo takes care of that and transparently.
[Discipulus]: thanks choroba i'll update my answer
[Lady_Aleena]: Hello Discipulus, Corion, choroba, and marioroy...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2017-05-26 08:46 GMT
Find Nodes?
    Voting Booth?