# assume you have a $toppath, which is where the traversal starts chdir $toppath or die "can't cd to $toppath: $!"; open( FIND, "find . -type d -print0 |" ) or die "can't run find: $!"; # find will traverse downward from current directory # (ie. $toppath), and because of the "-type d" option, # will only list the paths of directories contained here; # the "-print0" (thanks, etcshadow) sets a null byte as the # string terminator for each file name (don't rely on "\n", # which could be part of a file name). { local $/ = "\x0"; # added thanks to etcshadow's reply while ( my $dir = ) { chomp $dir; unless ( opendir( DIR, $dir )) { warn "$toppath/$dir: opendir failed: $!\n"; next; } while ( my $file = readdir( DIR )) { next if ( -d "$dir/$file" ); # outer while loop will handle all dirs # do what needs to be done with data files } closedir DIR; # anything else we need to do regarding this directory } } close FIND;