获取按Perl中的修改日期排序的文件列表

rkg*_*rkg 4 sorting perl date

我试图获取按修改日期排序的文件列表.我从排序目录修改了示例程序,并根据日期和时间列出了文件,并尝试运行它.

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循环排序文件列表的确切方式是什么?

cjm*_*cjm 7

该代码至少存在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

使用Perl排序功能.它更快,你会得到你想要的没有哈希.

文件大小,文件年龄:

@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)


mob*_*mob 4

在 中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)