in reply to How do I read all files in a directory recursively?

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; # ...do 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;

Replies are listed 'Best First'.
RE: Re: How do I read all files in a directory recursively?
by Anonymous Monk on Mar 04, 2000 at 04:21 UTC

    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 } }
RE: Re: How do I read all files in a directory recursively?
by plaid (Chaplain) on Mar 04, 2000 at 04:15 UTC
    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.