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

时间:2008-11-30 09:35:29

标签: perl last-modified

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

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

必须有更好的方法。

6 个答案:

答案 0 :(得分:24)

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

use File::DirList;
my @list = File::DirList::list('.', 'M');

就我个人而言,我不会使用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;

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

my @newest = @{$sorted_files[0]};
my $name = pop(@newest);

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


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

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

注意:对defined()结果的readdir()测试是因为如果您只测试if (my $file = readdir($DH))

,名为'0'的文件会导致循环失败

答案 1 :(得分: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";
}

答案 2 :(得分:11)

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

@list = `ls -t`;
$newest = $list[0];

答案 3 :(得分: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).

包裹grep的{​​{1}}过滤掉“。”和“..”UNIX(-ish)文件系统中的特殊文件。

答案 4 :(得分:2)

如果你不能让ls按照@Nathan的建议对你进行排序,那么你可以通过保持迄今为止看到的最新修改时间和相关文件名来优化你的过程,并在每次找到时替换它目录中的较新文件。您不需要保留任何您知道的文件比您目前为止看到的最新文件更旧,当然也不需要对它们进行排序,因为您可以在从目录中读取时检测哪个是最新文件。

答案 5 :(得分:-1)

主题是旧的,但也许有人会尝试它 - 它不是可移植的(仅限类Unix系统),但它非常简单且有效:

  

chdir $ directory或die“无法更改目录”;

     

我的$ newest_file = bash -c 'ls -t | head -1';

     

chomp $ newest_file;

     

打印“$ newest_file \ n”;