我试图获取按修改日期排序的文件列表.我从排序目录修改了示例程序,并根据日期和时间列出了文件,并尝试运行它.
sub get_sorted_files {
my $path = shift;
opendir my($dir), $path or die "can't opendir $path: $!";
my %hash = map {$_ => (stat($_))[9]}
map { "$dir$_" }
grep { m/.*/i }
readdir $dir;
closedir $dir;
return %hash;
}
my %files = get_sorted_files(".");
foreach my $keys (sort{$files{$a} <=> $files{$b}} keys %files) {
print "$keys\t", scalar localtime($files{$keys}), "\n";
}
Run Code Online (Sandbox Code Playgroud)
我使用Strawberry Perl版本5.12.1.0 在我的Windows XP 32位机器上运行它.
Windows上的目录列表是:

输出是:

输出对我来说没有多大意义.这段代码出了什么问题,foreach循环排序文件列表的确切方式是什么?
该代码至少存在2个问题.这是一个更好的版本:
use strict;
use warnings; # I bet you weren't using this, because it produced a lot
sub get_sorted_files {
my $path = shift;
opendir my($dir), $path or die "can't opendir $path: $!";
my %hash = map {$_ => (stat($_))[9] || undef} # avoid empty list
map { "$path$_" }
readdir $dir;
closedir $dir;
return %hash;
}
my %files = get_sorted_files("./");
foreach my $key (sort{$files{$a} <=> $files{$b}} keys %files) {
print "$key\t", scalar localtime($files{$key}), "\n";
}
Run Code Online (Sandbox Code Playgroud)
首先,您$dir在原始代码中重命名$path,但没有map在行中更改它.你$dir是一个目录句柄; 这就是GLOB(0x ...)的来源.
其次,所有修改日期均为"Wed Dec 31 16:00:00 1969",因为您传递了错误的路径名stat. (stat($_))[9]返回一个空列表(因为你正在寻找一个文件,GLOB(0x3f9b38)status.txt而不是正确的路径名),所以散列实际上包含文件名作为键和值.第一个文件名是一个键,第二个是它的值,第三个是下一个键,依此类推. localtime正在将文件名转换为数字(产生0),然后将纪元时间0(1-Jan-1970 0:00:00 UTC)转换为您的时区.
第三,它希望$path以目录分隔符结束,而你正在传递".".您需要传递"./"或更好地修复它,以便函数在需要时附加分隔符.
第四,grep不再做任何事情,应该删除.(在原始代码中,它只选择了某些文件名,但您更改了模式以匹配任何内容.)
至于它如何对文件名进行排序: get_sorted_files返回路径名和修改时间列表,您将其存储到%files哈希中. keys %files返回键列表(文件名),并通过相关值(修改时间)的数字比较对它们进行排序.
小智 6
文件大小,文件年龄:
@s = sort {-s $ a <=> -s $ b || -M $ b <=> -M $ a} @a;
知道了上面的内容,我们可以说如下:
sub get_sorted_files {
my $path = shift;
opendir my($dirh), $path or die "can't opendir $path: $!";
my @flist = sort { -M $a <=> -M $b } # Sort by modification time
map { "$path/$_" } # We need full paths for sorting
readdir $dirh;
closedir $dirh;
return @flist;
}
Run Code Online (Sandbox Code Playgroud)
在 中get_sorted_files,$dir是一个 glob,而不是目录名称。也许你的意思是$path?
my %hash = map {$_ => (stat($_))[9]}
map { "$path/$_" } # $path, not $dir
grep { m/.*/i }
readdir $dir;
Run Code Online (Sandbox Code Playgroud)