我想在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?
答案 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命令。