我想要目录中每个文件的最后修改时间。为了确保我的循环正常工作,我打印$ _,然后我看到目录的文件名:
{{1}}
我收到此错误
在连接(。)或字符串
中使用未初始化的值$ epoch_timestamp
我做错了什么?
答案 0 :(得分:2)
readdir
仅返回文件的名称。如果您当前的工作目录不同,则必须像使用opendir
参数一样构建完整路径。最简单的方法是在列表中使用map
for
循环
我很关心你的陈述
opendir( D, $path . '\/' . $_ ) or die "$!";
将\/
放在$path
和$_
之间。我认为你只需要/
,但插入变量最简单
opendir( D, "$path/$_" ) or die "$!";
但$_
来自数组@Files
。如果这些确实是文件名,则opendir
将失败。它们需要是目录名
在我的解决方案中,我将变量$dir
构建为
my $dir = "$path/$_"
这样它就可以用于opendir
的调用,也可以构建以下for
循环中文件的完整路径
请注意,我还使用了词法目录句柄my $dh
,它远远优于全局句柄D
for ( @Files ) {
my $dir = "$path/$_";
opendir my $dh, $dir or die $!;
my @textfiles = grep { ! /^\.{1,2}$/ } readdir $dh;
for ( map { "$dir/$_" } @textfiles ) {
# print "$_\n"; <----the file names.
my $epoch_timestamp = ( stat( $_ ) )[9];
print "$epoch_timestamp\n";
}
答案 1 :(得分:1)
或者对于上述完美答案,您可以使用一些模块,让您的生活更轻松。 :)喜欢:Path::Tiny [1]
use 5.014;
use warnings;
use Path::Tiny;
my $path = path('/etc');
my @Files = qw(defaults cups ssl);
for my $dir (@Files) {
my @textfiles = $path->child($dir)->children;
for my $file (@textfiles) {
say "$file: ", $file->stat->mtime;
}
}
当然,上面的嵌套循环可以写成
for my $dir (@Files) {
my @textfiles = $path->child($dir)->children;
say "$_: ", $_->stat->mtime for (@textfiles);
}
并且还不需要将文件列表存储到@textfiles
中,因此可以将其缩减为:
for my $dir (@Files) {
say "$_: ", $_->stat->mtime for ( $path->child($dir)->children );
}
答案 2 :(得分:0)
readdir
仅返回目录中文件的名称。您需要提供文件的限定路径stat
。
my $dir_qfn = ...;
opendir(my $dh, $dir_qfn)
or do {
warn("Can't read dir \"$dir_qfn\": $!\n");
next;
};
while (defined( my $fn = readdir($dh) )) {
next if $fn =~ /^\.\.?\z/;
my $qfn = "$dir_qfn/$fn";
my $mtime = ( stat($qfn) )[9];
defined($mtime)
or do {
warn("Can't stat file \"$file_qfn\": $!\n");
next;
};
...
}
答案 3 :(得分:0)
使用glob
代替
my $dir = ...;
my %ts =
map { $_ => (stat $_)[9] }
grep { !m{/\.\.?\z} } #/
glob "\Q$dir\E/{*,.*}";
say "ts{$_} => $_" for sort keys %ts;
我使用哈希 name =&gt;时间戳以在数据结构中收集它们。模式$dir/{*,.*}
也可以捕获点文件,或者它只是$dir/*
。
grep
过滤掉.
和..
个文件名,在m{..}
匹配的路径中找到。它的模式需要\Q..\E
来防止特定目录名的注入错误。它也会转义空格,因此不需要File::Glob
及其:bsd_glob
选项。感谢ikegami的评论。
如果您希望一次处理一个文件,请使用glob
检索列表,然后迭代它。