ls -ltr in perl

时间:2010-08-11 13:03:37

标签: perl directory

我想在perl脚本中复制ls -ltr unix命令,而不使用反引号,exec或系统。以下脚本正在运行:

use strict;
my $dir="/abc/xyz/log";
opendir(DIR, $dir) or die "Can not open $dir $!";
my @latest = (sort {-M $b <=> -M $a} <$dir/*>);
my @latest2= grep { !/^\./ && -f "$_"} @latest;
closedir DIR;

问题:如何将sort和grep合并为一行,以便我可以取消@ latest2?

5 个答案:

答案 0 :(得分:10)

这里提出的解决方案已经是o.k.但是如果在非常大的目录上使用,可能会变慢,然后sort函数会反复对相同的文件重复应用-M。因此,可以使用 Schwartzian Transform来避免这种情况(如有必要):

...

my @sorted_fnames =
         map  $_->[0]       ,          # ↑ extract file names
         sort { $a->[1] <=> $b->[1] }  # ↑ sort ascending after mdate 
         map  [$_, -M $_]   ,          # ↑ pre-build list for sorting 
         grep ! /^\.\.?$/   ,          # ↑ extract file names except ./..
      readdir $dirhandle;              # ↑ read directory entries

...

此致

RBO

答案 1 :(得分:2)

my @latest = grep { !/^\./ && -f "$_"} (sort {-M $b <=> -M $a} <$dir/*>);

答案 2 :(得分:1)

像这样:

my @latest = grep { !/^\./ && -f "$_"} (sort {-M $b <=> -M $a} <$dir/*>);

答案 3 :(得分:0)

Perl流水线命令遵循赋值运算符的从右到左的方向。所以你必须要倒退。这是最接近的操作,它首先完成等号。

当然,现在对我来说这是第二天性,我很少想到它可能会出现“后退词”。但是如果你首先进行grep然后排序,那么你将会有一个更加压缩的排序,并且最好的排序是半二次的,减少你要排序的项目数量是很有意义的。

当句柄超出范围时关闭,你可以这样做:

my @list 
    = sort {-M $b <=> -M $a} 
      grep { !/^\./ && -f "$_"} 
      <$dir/*>
    ;

当您使用glob执行此操作时,您无需打开目录句柄。但如果你是,你可以这样做:

my @list = sort ... grep ... 
           do { opendir( my $dh, $dir ) or die "Cannot open '$dir': $!"; 
                readdir( $dh ) 
              };

答案 4 :(得分:0)

Unix ls已作为Perl Power Tools (ls)套件的一部分在Perl中实现。

还实现了许多其他Unix命令。