Perl文件查找模块应用示例
2013-07-10 11:01:13

本站赞助商链接,请多关照。 Perl环境下的文件查找可以使用多种方式来实现,当然使用模块来实现会方便很多,目前主要有的相关模块有:File::FindFile::Find::Rule,现就其使用方法及应用进行举例。

-------------------------------
综合查找示例
查找某目录下所有在某时间段中所产生的png格式文件。
my $srceDir   = "/home/freeoabackup/site/";
my $startDate = "2013-01-01";
my $endDate   = "2013-02-28";

use strict;
use File::Find ();
use POSIX qw(mktime);
use Data::Dumper;
use vars qw/*name *dir *prune/;

*name=*File::Find::name;
*dir=*File::Find::dir;
*prune=*File::Find::prune;

my ($sDay,$eDay)=map {
 my ($year,$month,$day)=split("-",$_);
 (time()-mktime(0,0,0,$day,$month-1,$year-1900))/86400
} ($startDate,$endDate);

print "$sDay--$eDay\n";

sub wanted {
 my ($dev,$ino,$mode,$nlink,$uid,$gid);

 (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
 -f _ && /png$/ && (-M _ < $sDay) && !(-M _ < $eDay) && print("$name\n");
}

File::Find::find({wanted=>\&wanted},$srceDir);

-------------------------------
How to stop File::Find entering directory recursively-停止进入递归目录查找

---------------
使用prune来实现
$File::Find::prune can be used to avoid recursing into a directory.
---------------
use File::Find qw( find );
my $root = '.';
find({
   wanted   => sub { listfiles($root); },
   no_chdir => 1,
}, $root);

sub listfiles {
 my ($root) = @_;
 print "$File::Find::name\n";
 $File::Find::prune = 1  # Don't recurse.
  if $File::Find::name ne $root;
}

它会将工作目录下的所有文件(目录)列出来。

---------------
使用'prune'的另一示例,针对是特定目录。
use File::Basename qw( basename );
use File::Find qw( find );

my %skip = map { $_ => 1 } qw( .git .svn freeoa);

find({
 wanted   => \&listfiles,
 no_chdir => 1,
}, '.');

sub listfiles {
if ($skip{basename($File::Find::name)}) {
 $File::Find::prune = 1;
 return;
}
print "$File::Find::name\n";
}

---------------
使用'File::Find::Rule'
An interface for Find::File--with maxdepth(1) to stop directory recursion.

use Modern::Perl;
use File::Find::Rule;

my $directory = '.';
my @files = File::Find::Rule->maxdepth(1)
 ->file
 ->name( '*.txt' )
 ->in( $directory );
 
say for @files;

In this case, only *.txt file names will be passed to @files.

---------------
使用'preprocess'参数

这是最简单的方法,移除工作目录下所有的子目录,然后由wanted函数来处理。

The parameter list passed to the preprocess subroutine is the nodes in the current directory - the output of readdir. The returned value is the same list but sorted and filtered according to how you want them to be processed. This code just removes all directories.

在最后输出时,使用'File::Spec'模块中的'rel2abs'函数将前面的'./'移除,但不要使用'no_chdir'这个参数,因此它会打乱当前的工作目录。

use File::Find 'find';
use File::Spec;
find({ wanted => \&listfiles, preprocess => \&nodirs }, '.');
sub nodirs {
  grep ! -d, @_;
}

sub listfiles {
  my $filename = File::Spec->abs2rel($File::Find::name);
  print $filename, "\n";
}

-------------------------------