使用 File::Find 模块时无输出
No output when using File::Find module
我想统计 modify_time
在 $atime
和 $btime
之间的文件总数。这是我的代码的一部分,但它没有 return 任何东西。怎么了?
sub mtime_between {
my $mtime=0;
my $counts=0;
$mtime = (stat $File::Find::name)[9] if -f $File::Find::name;
if ($mtime > $atime and $mtime < $btime) {
return sub { print ++$counts,"$File::Find::name\n"};
}
当我调用子程序时,我什么也没得到。
find(\&mtime_between,"/usr");
你不应该 return 函数。
find()
does a depth-first search over the given @directories
in the order they are given. For each file or directory found, it calls the &wanted
subroutine.
在想要的功能中,你应该直接做你想做的事情。 return 函数引用将不起作用,这就是您遇到问题的原因。
所以你实际上想要更像的东西:
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw{say};
use File::Find;
use Data::Dumper;
my ($atime, $btime) = (1461220840, 1561220844);
sub findFilesEditedBetweenTimestamps {
my ($atime, $btime, $path) = @_;
my $count = 0;
my @files = ();
my $mtime_between = sub {
my $mtime = 0;
$mtime = (stat $File::Find::name)[9] if -f $File::Find::name;
if ($mtime > $atime and $mtime < $btime) {
push @files, $File::Find::name;
$count++;
}
return;
};
find ($mtime_between, $path);
say "Found a total of $count files";
say "Files:";
print Dumper(@files);
}
findFilesEditedBetweenTimestamps($atime, $btime, "./");
我得到:
Found a total of 2 files
Files:
$VAR1 = './test.txt';
$VAR2 = './test.pl';
如前所述,wanted
子例程返回的值将被忽略。从回调中返回回调对于某些人来说可能太过分了!
这可能很有趣。我使用了 File::stat
module to make extraction of the modification time more readable, and Time::Piece
,因此 $atime
和 $btime
可以用可读字符串而不是纪元值
来表示
除非您愿意,否则无需为 wanted
函数编写单独的子例程——您可以在 find
调用中使用匿名子例程。如果节点不是文件
,那么从 wanted
子例程中简单地 return
是最简单的
#!/usr/bin/env perl
use strict;
use warnings 'all';
use File::Find;
use File::stat;
use Time::Piece;
sub count_files_between_times {
my ($from, $to, $path) = @_;
my $count = 0;
find(sub {
my $st = stat($_) or die $!;
return unless -f $st;
my $mtime = $st->mtime;
++$count if $mtime >= $fromand $mtime <= $to;
}, $path);
print "Found a total of $count files\n";
}
my ($from, $to) = map {
Time::Piece->strptime($_, '%Y-%m-%dT%H:%M:%S')->epoch;
} '2016-04-19T00:00:00', '2019-04-22T00:00:00';
count_files_between_times($from, $to, '/usr');
更新
有些人更喜欢 File::Find::Rule
模块。我个人非常不喜欢它,而且看过源代码后我对它非常警惕,但它确实使这个过程更加简洁
请注意,File::Find::Rule
位于 File::Find
之上,后者为它完成了繁重的工作。所以它本质上是 wanted
子例程
的另一种写法
use File::Find::Rule ();
sub count_files_between_times {
my ($from, $to, $path) = @_;
my @files = File::Find::Rule->file->mtime(">= $from")->mtime("<= $to")->in($path);
printf "Found a total of %d files\n", scalar @files;
}
或者如果您愿意,您可以一次添加一个语句的限制
use File::Find::Rule ();
sub count_files_between_times {
my ($from, $to, $path) = @_;
my $rule = File::Find::Rule->new;
$rule->file;
$rule->mtime(">= $from");
$rule->mtime("<= $to");
my @files = $rule->in($path);
printf "Found a total of %d files\n", scalar @files;
}
这两个替代子例程都产生与上述原始子例程相同的结果
我想统计 modify_time
在 $atime
和 $btime
之间的文件总数。这是我的代码的一部分,但它没有 return 任何东西。怎么了?
sub mtime_between {
my $mtime=0;
my $counts=0;
$mtime = (stat $File::Find::name)[9] if -f $File::Find::name;
if ($mtime > $atime and $mtime < $btime) {
return sub { print ++$counts,"$File::Find::name\n"};
}
当我调用子程序时,我什么也没得到。
find(\&mtime_between,"/usr");
你不应该 return 函数。
find()
does a depth-first search over the given@directories
in the order they are given. For each file or directory found, it calls the&wanted
subroutine.
在想要的功能中,你应该直接做你想做的事情。 return 函数引用将不起作用,这就是您遇到问题的原因。
所以你实际上想要更像的东西:
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw{say};
use File::Find;
use Data::Dumper;
my ($atime, $btime) = (1461220840, 1561220844);
sub findFilesEditedBetweenTimestamps {
my ($atime, $btime, $path) = @_;
my $count = 0;
my @files = ();
my $mtime_between = sub {
my $mtime = 0;
$mtime = (stat $File::Find::name)[9] if -f $File::Find::name;
if ($mtime > $atime and $mtime < $btime) {
push @files, $File::Find::name;
$count++;
}
return;
};
find ($mtime_between, $path);
say "Found a total of $count files";
say "Files:";
print Dumper(@files);
}
findFilesEditedBetweenTimestamps($atime, $btime, "./");
我得到:
Found a total of 2 files
Files:
$VAR1 = './test.txt';
$VAR2 = './test.pl';
如前所述,wanted
子例程返回的值将被忽略。从回调中返回回调对于某些人来说可能太过分了!
这可能很有趣。我使用了 File::stat
module to make extraction of the modification time more readable, and Time::Piece
,因此 $atime
和 $btime
可以用可读字符串而不是纪元值
除非您愿意,否则无需为 wanted
函数编写单独的子例程——您可以在 find
调用中使用匿名子例程。如果节点不是文件
wanted
子例程中简单地 return
是最简单的
#!/usr/bin/env perl
use strict;
use warnings 'all';
use File::Find;
use File::stat;
use Time::Piece;
sub count_files_between_times {
my ($from, $to, $path) = @_;
my $count = 0;
find(sub {
my $st = stat($_) or die $!;
return unless -f $st;
my $mtime = $st->mtime;
++$count if $mtime >= $fromand $mtime <= $to;
}, $path);
print "Found a total of $count files\n";
}
my ($from, $to) = map {
Time::Piece->strptime($_, '%Y-%m-%dT%H:%M:%S')->epoch;
} '2016-04-19T00:00:00', '2019-04-22T00:00:00';
count_files_between_times($from, $to, '/usr');
更新
有些人更喜欢 File::Find::Rule
模块。我个人非常不喜欢它,而且看过源代码后我对它非常警惕,但它确实使这个过程更加简洁
请注意,File::Find::Rule
位于 File::Find
之上,后者为它完成了繁重的工作。所以它本质上是 wanted
子例程
use File::Find::Rule ();
sub count_files_between_times {
my ($from, $to, $path) = @_;
my @files = File::Find::Rule->file->mtime(">= $from")->mtime("<= $to")->in($path);
printf "Found a total of %d files\n", scalar @files;
}
或者如果您愿意,您可以一次添加一个语句的限制
use File::Find::Rule ();
sub count_files_between_times {
my ($from, $to, $path) = @_;
my $rule = File::Find::Rule->new;
$rule->file;
$rule->mtime(">= $from");
$rule->mtime("<= $to");
my @files = $rule->in($path);
printf "Found a total of %d files\n", scalar @files;
}
这两个替代子例程都产生与上述原始子例程相同的结果