使用Perl按天数删除子文件夹和文件

时间:2016-10-11 18:07:05

标签: perl

Perl新手,只使用了3次。当它们超过一周时,我需要从父目录中删除文件和子文件夹。我在使用-M之前删除了文件但从未使用过子文件夹。当我运行下面的详细信息时,子文件夹中不会删除任何文件,并且子文件夹中存在一周以上的文件。对于子文件夹中的所有文件,测试消息显示'myAge'为零。不知道我错过了什么。非常感谢任何帮助。

msg ("\n");
msg ("Start: \n");


my $parent  = 'C:/temp/XYZ';
my ($par_dir, $sub_dir);

opendir($par_dir, $parent);
msg " parent is $parent \n";

while (my $sub_folders = readdir($par_dir)) {
    next if ($sub_folders =~ /^..?$/);  # skip . and ..

    my $path = $parent . '/' . $sub_folders;

    next unless (-d $path);   # skip anything that isn't a directory
    next unless ( -M $subfolder <  7  );

    msg " subfolder is $sub_folders is old enough to delete \n";

    opendir($sub_dir, $path);
    while (my $file = readdir($sub_dir)) {

    # for testing       
    my $myAge = (-M $file) ;
    msg " age ... $myAge __ file ...  $file\n" ;    

        if ( -M $file >   7  ) {
        msg " going to delete this file...  $file \n";
        } else {
        msg " will keep this file not old enough $file\n";
        }

    }   
    closedir($sub_dir);
}
closedir($par_dir);

2 个答案:

答案 0 :(得分:1)

假设您使用的是* nix系统..

有时候调用find

会更容易
find /foo/bar/ -type d -mtime +7 -exec rm -rf {} \;

find /foo/bar/ -type f -mtime +7 -exec rm {} \;

将删除所有7天(d)爱好者或(f)iles

答案 1 :(得分:0)

如果这只是你第三次使用Perl,那么祝贺!但你的代码中存在一些问题:

  • 始终use strict;use warnings;添加到您的代码中。这将警告(超越其他人) 未定义的变量并消除常见错误。
  • 您的$sub_folders$subfolder的拼写错误。 use strict;use warnings;会显示出来。
  • readdir的返回值不包含父目录。 docs说:

      

    如果您计划对readdir的返回值进行文件测试,那么您会更好   在前面有问题的目录。否则,因为我们没有在那里,   它会测试错误的文件。

    我认为这就是这里发生的事情。

我通过将目录添加到文件名来改变你的代码,现在它似乎正常工作。 我还编写了一个msg函数,它只是print给定的参数。你会省略它 如果你有一个真实的&#34; msg功能。

#!/usr/bin/env perl

use strict;
use warnings;

sub msg
{
    print @_;
}

msg("\n");
msg("Start: \n");

my $parent = 'C:/temp/XYZ';
my ( $par_dir, $sub_dir );

opendir( $par_dir, $parent ) or die "cannot opendir $parent: $!\n";;
msg " parent is $parent \n";

while ( my $sub_folders = readdir($par_dir) ) {
    next if ( $sub_folders =~ /^..?$/ );    # skip . and ..

    my $path = "$parent/$sub_folders";

    next unless ( -d $path );               # skip anything that isn't a directory
    next unless ( -M $path < 7 );

    msg " subfolder is $sub_folders is old enough to delete \n";

    opendir( $sub_dir, $path ) or die "cannot opendir $path: $!\n";
    while ( my $file = readdir($sub_dir) ) {

        # for testing
        my $myAge = ( -M "$path/$file" );
        msg " age ... $myAge __ file ...  $path/$file\n";

        if ( -M "$path/$file" > 7 ) {
            msg " going to delete this file...  $path/$file \n";
        } else {
            msg " will keep this file not old enough $path/$file\n";
        }

    }
    closedir($sub_dir);
}
closedir($par_dir);

在此代码中有一些可以改进的东西。

  1. 我不会检查目录的修改时间并删除next unless ( -M $path < 7 );。 我的印象是目录的属性(大小,时间)随意改变 - 至少我不能 永远想出一个模式,但也许我对此太愚蠢了。
  2. 为了加快速度,-X运算符(如-d-M等)会缓存最后一个文件的结果。所以与其 写作

    next unless ( -d $path );
    next unless ( -M $path < 7 );
    

    可以

    next unless ( -d $path );
    next unless ( -M _ < 7 ); # the '_' means: get '-M' of $path
    

    有关详细信息,请参阅-X。基本上-X获取a的所有属性 给定文件(如大小,类型,访问时间,修改时间等)。如果您传递下划线_作为 后续调用中的文件名,然后返回上一次调用的结果(使用真实文件名) 另一个(昂贵的)系统调用已保存。

  3. 算法只考虑起始目录下的一个目录,即它不会递归地工作。 根据您的实际需要,这可能会也可能不会。