9.7. Processing All Files in a Directory RecursivelyProblemYou want to do something to each file and subdirectory in a particular directory. SolutionUse the standard File::Find module. use File::Find; sub process_file { # do whatever; } find(\&process_file, @DIRLIST); Discussion
File::Find provides a convenient way to process a directory recursively. It does the directory scans and recursion for you. All you do is pass
Before calling your function,
This simple example demonstrates File::Find. We give @ARGV = qw(.) unless @ARGV; use File::Find; find sub { print $File::Find::name, -d && '/', "\n" }, @ARGV;
This prints a
The following program prints the sum of everything in a directory. It gives use File::Find; @ARGV = ('.') unless @ARGV; my $sum = 0; find sub { $sum += -s }, @ARGV; print "@ARGV contains $sum bytes\n"; This code finds the largest single file within a set of directories: use File::Find; @ARGV = ('.') unless @ARGV; my ($saved_size, $saved_name) = (-1, ''); sub biggest { return unless -f && -s _ > $saved_size; $saved_size = -s _; $saved_name = $File::Find::name; } find(\&biggest, @ARGV); print "Biggest file $saved_name in @ARGV is $saved_size bytes long.\n";
We use It's simple to change this to find the most recently changed file: use File::Find; @ARGV = ('.') unless @ARGV; my ($age, $name); sub youngest { return if defined $age && $age > (stat($_))[9]; $age = (stat(_))[9]; $name = $File::Find::name; } find(\&youngest, @ARGV); print "$name " . scalar(localtime($age)) . "\n";
The File::Find module doesn't export its Example 9.2: fdirs#!/usr/bin/perl -lw # fdirs - find all directories @ARGV = qw(.) unless @ARGV; use File::Find (); sub find(&@) { &File::Find::find } *name = *File::Find::name; find { print $name if -d } @ARGV;
Our find sub { print $File::Find::name if -d }, @ARGV; we can write the more pleasant: find { print $name if -d } @ARGV; See AlsoThe documentation for the standard File::Find and Exporter modules (also in Chapter 7 of Programming Perl ); your system's find (1) manpage; Recipe 9.6 |
|