使用Perl快速清理目录

时间:2015-01-06 13:19:24

标签: linux perl rm

我需要在我的网络服务器上清理包含数百万个日志文件的目录。我发现了this great article如何做到这一点。然而,在我所感兴趣的单行中有一些有趣的事情。

这是我感兴趣的Perl代码:

for(<*>){((stat)[9]<(unlink))}

使用perl -e 'code'运行。

所以,这是我的问题:

  1. for(<*>)构造 - 我假设它遍历当前目录中的文件。但它在哪里存储迭代器?
  2. statunlink函数期望至少有一个参数,我假设......但它在哪里?
  3. 为什么将调用(stat)[9]的结果与调用(unlink)的结果进行比较?它会带来什么结果?
  4. 抱歉,我是一个非常善良的人,因此我不理解Perl的所有缩写。这就是我问这个问题的原因。

    谢谢!

3 个答案:

答案 0 :(得分:3)

一个班轮需要很多快捷方式:

  1. <*>是钻石运营商的特例。您无法访问迭代器对象,就像在其他语言中一样。在这里,它调用glob函数。在列表上下文中,它返回一个来自所有结果的列表(它们是文件的行,或者,就像你的情况一样,是一个diretory的内容。它的返回值传递给for,它迭代一个列表并对$_中的值进行别名。$_是&#34;默认变量&#34;对于许多函数...
  2. 这就把我们带到了这里。许多核心函数默认为$_,没有参数。请unlinkstat
  3. (stat)[9]表示在列表上下文中执行stat并选择第10个结果(索引从零开始,这是修改时间)。 (将其与$foo[9])之类的数组访问进行比较。

答案 1 :(得分:3)

代码

for(<*>){((stat)[9]<(unlink))}

相当于:

for my $file (<*>) {
    my $mtime = (stat($file))[9];
    $mtime < unlink($file);
}

<*>也可以替换为可能更具可读性的glob "*"

代码将删除当前目录中的所有文件。它不会删除目录。

请注意,循环中的最后一个语句是完全冗余的。如果use warnings生效,则会发出警告:

Useless use of numeric lt (<) in void context

为了使这段代码有意义,我希望进行比较实际上很重要,例如将$mtime与某些时间进行比较,以了解哪些日志是旧的,例如:

if ($mtime < $oldtime) {
    unlink $file or die "Cannot unlink $file: $!";
}

另请注意,删除文件时检查失败可能是明智的。

答案 2 :(得分:1)

  
      
  1. for(&lt; *&gt;)构造 - 我假设它遍历当前目录中的文件。但它在哪里存储迭代器?
  2.   

for-loops可用于迭代数组/列表,因此如果<*>生成一个列表,那么您的代码只是一个mill for循环的运行。事实证明<*>是另一种拼写glob()的方法,它有点像检索文件名的正则表达式,而glob()在列表上下文中返回一个列表 - 是for循环提供的上下文。请参阅:http://perldoc.perl.org/functions/glob.html

请注意,单引号使shell不会扩展*,这会阻止perl看到它。