【问题标题】:Delete all files in a directory, but keep the directory?删除目录中的所有文件,但保留目录?
【发布时间】:2014-10-18 08:18:04
【问题描述】:

最简单的方法是:

  • 删除给定目录 /files/axis (unlink) 中的所有文件
  • 仅限超过 30 天的文件
  • 应该保留空目录(不要rmdir

【问题讨论】:

标签: perl history delete-file


【解决方案1】:

这将按照您的要求进行。它使用opendir/readdir 列出目录。 stat 获取所有必要的信息,随后的 -f _-M _ 调用检查该项目是否为文件并且是否超过 30 天而不重复 stat 调用。

use strict;
use warnings;
use 5.010;
use autodie;
no autodie 'unlink';

use File::Spec::Functions 'catfile';

use constant ROOT => '/path/to/root/directory';

STDOUT->autoflush;

opendir my ($dh), ROOT;

while (readdir $dh) {
  my $fullname = catfile(ROOT, $_);
  stat $fullname;

  if (-f _ and -M _ > 30) {
    unlink $fullname or warn qq<Unable to delete "$fullname": $!\n>;
  }
}

如果您想删除给定目录下任何地方的文件,正如我开始相信的那样,那么您需要File::Find。整体结构与我的原始代码差别不大。

use strict;
use warnings;
use 5.010;
use autodie;
no autodie 'unlink';

use File::Spec::Functions qw/ canonpath catfile /;
use File::Find;

use constant ROOT => 'E:\Perl\source';

STDOUT->autoflush;

find(\&wanted, ROOT);

sub wanted {
  my $fullname = canonpath($File::Find::name);
  stat $fullname;

  if (-f _ and -M _ < 3) {
    unlink $fullname or warn qq<Unable to delete "$fullname": $!\n>;
  }
}

【讨论】:

    【解决方案2】:

    更简单的方法是“不使用 perl”。

    find /files/axis -mtime +30 -type f -exec rm {} \;
    

    【讨论】:

      【解决方案3】:

      对于跨平台兼容的 Perl 解决方案,我会推荐以下两个模块之一。

      1. Path::Class

        #!/usr/bin/env perl
        use strict;
        use warnings;
        
        use Path::Class;
        
        my $dir = dir('/Users/miller/devel');
        
        for my $child ( $dir->children ) {
            next if $child->is_dir || ( time - $child->stat->mtime ) < 60 * 60 * 24 * 30;
            # unlink $child or die "Can't unlink $child: $!"
            print $child, "\n";
        }
        
      2. Path::Iterator::Rule

        #!/usr/bin/env perl
        use strict;
        use warnings;
        
        use Path::Iterator::Rule;
        
        my $dir = '/foo/bar';
        
        my @matches = Path::Iterator::Rule->new
                                          ->file
                                          ->mtime( '<' . ( time - 60 * 60 * 24 * 30 ) )
                                          ->max_depth(1)
                                          ->all($dir);
        
        print "$_\n" for @matches;
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-09
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        • 2021-01-22
        • 2013-07-31
        • 1970-01-01
        • 2010-11-05
        相关资源
        最近更新 更多