如何在目录中找到最新创建的文件?

Tom*_*ner 20 perl last-modified

在Perl中是否有一种优雅的方式来查找目录中的最新文件(最新的修改日期)?

到目前为止我所搜索的文件是搜索我需要的文件,并为每个文件获取修改时间,推入包含文件名,修改时间的数组,然后对其进行排序.

肯定有更好的办法.

Aln*_*tak 24

如果您需要一个排序列表(而不仅仅是第一个,请参阅Brian的答案),您的方式是"正确的"方式.如果您不想自己编写该代码,请使用代码

use File::DirList;
my @list = File::DirList::list('.', 'M');
Run Code Online (Sandbox Code Playgroud)

就个人而言,我不会采用这种ls -t方法 - 涉及分支另一个程序而且它不可移植.几乎我称之为"优雅"!


关于rjray的解决方案手动编码解决方案,我稍微改变一下:

opendir(my $DH, $DIR) or die "Error opening $DIR: $!";
my @files = map { [ stat "$DIR/$_", $_ ] } grep(! /^\.\.?$/, readdir($DH));
closedir($DH);

sub rev_by_date { $b->[9] <=> $a->[9] }
my @sorted_files = sort rev_by_date @files;
Run Code Online (Sandbox Code Playgroud)

在此之后,@sorted_files包含排序列表,其中第0个元素是最新文件,每个元素本身包含对结果的引用stat,文件名本身位于最后一个元素中:

my @newest = @{$sorted_files[0]};
my $name = pop(@newest);
Run Code Online (Sandbox Code Playgroud)

这样做的好处是,如果需要,以后更容易更改排序方法.


编辑:这里的目录扫描,这也确保了只有普通的文件添加到列表中更容易阅读的(但更长时间)的版本:

my @files;
opendir(my $DH, $DIR) or die "Error opening $DIR: $!";
while (defined (my $file = readdir($DH))) {
  my $path = $DIR . '/' . $file;
  next unless (-f $path);           # ignore non-files - automatically does . and ..
  push(@files, [ stat(_), $path ]); # re-uses the stat results from '-f'
}
closedir($DH);
Run Code Online (Sandbox Code Playgroud)

注意:defined()对结果的测试readdir()是因为如果你只测试一个名为'0'的文件会导致循环失败if (my $file = readdir($DH))


bri*_*foy 14

您不需要将所有修改时间和文件名保留在列表中,您可能不应该这样做.您需要做的就是查看一个文件,看看它是否比您之前看到的最旧文件更旧:

{
    opendir my $dh, $dir or die "Could not open $dir: $!";

    my( $newest_name, $newest_time ) = ( undef, 2**31 -1 );

    while( defined( my $file = readdir( $dh ) ) ) {
        my $path = File::Spec->catfile( $dir, $file );
        next if -d $path; # skip directories, or anything else you like
        ( $newest_name, $newest_time ) = ( $file, -M _ ) if( -M $path < $newest_time );
    }

    print "Newest file is $newest_name\n";
}
Run Code Online (Sandbox Code Playgroud)

  • 你遇到了一个真正的问题,但是出于错误的原因.在程序启动后修改文件时,`-M`为负.如果尚未定义,我应该设置最新的时间.$ newest_time不会自动初始化为零:如果它未定义则转换为0并且我以数字方式使用它(如在`<`运算符中).你也不想将它设置为某种神奇的值.在你有意义之前,你希望缺少价值.:) (2认同)

Nat*_*man 11

你可以尝试使用shell的ls命令:

@list = `ls -t`;
$newest = $list[0];
Run Code Online (Sandbox Code Playgroud)


rjr*_*ray 6

假设你知道$DIR你想要查看:

opendir(my $DH, $DIR) or die "Error opening $DIR: $!";
my %files = map { $_ => (stat("$DIR/$_"))[9] } grep(! /^\.\.?$/, readdir($DH));
closedir($DH);
my @sorted_files = sort { $files{$b} <=> $files{$a} } (keys %files);
# $sorted_files[0] is the most-recently modified. If it isn't the actual
# file-of-interest, you can iterate through @sorted_files until you find
# the interesting file(s).
Run Code Online (Sandbox Code Playgroud)

grep包裹该readdir过滤掉了"" 和".."UNIX(-ish)文件系统中的特殊文件.