我有以下文件
./path/to/stuff1/file1 (x)
./path/to/stuff1/file2
./path/to/stuff1/file3
./path/to/stuff2/file1
./path/to/stuff2/file2 (x)
./path/to/stuff2/file3
./path/to/stuff3/file1 (x)
./path/to/stuff3/file2
./path/to/stuff3/file3
我标记了我最后触及的文件。我想得到那些标记的文件。换句话说:
我构造了bash命令
for line in $( find . -name 'file*' -type f | awk -F/ 'sub($NF,x)' | sort | uniq ); do
find $line -name 'file*' -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2 -d' '
done
我可以使用system
命令在perl中使用并转义$
。是否可以直接在perl中执行此操作,或者您认为我的方法是否正常?
修改
如果可能,任务应该在perl中完成而不使用外部模块。
EDIT2
抱歉,我注意到我的问题不明确。我认为@TLP的答案可行但我必须澄清:我想检查每个文件夹中的最新文件,例如 stuff1 中的最新文件。说我做
touch ./path/to/stuff1/file1
touch ./path/to/stuff2/file2
touch ./path/to/stuff3/file1
在我运行脚本之前。然后输出:
./path/to/stuff1/file1
./path/to/stuff2/file2
./path/to/stuff3/file1
对于不同的东西,文件名可以相同,但每个路径只能输出一个文件。
@codnodder的脚本执行此操作,但我希望仅搜索文件名而不是完整路径。所以我想搜索以文件开头的所有文件,脚本应该递归搜索。
答案 0 :(得分:1)
您的find
命令可以使用File::Find
find
命令进行模拟。这是Perl 5中的核心模块,几乎肯定已经在您的系统上。要检查文件修改时间,可以使用-M
文件测试。
这样的事情:
use strict;
use warnings;
use File::Find;
my %times;
find(\&wanted, '.');
for my $dir (keys %times) {
print $times{$dir}{file}, "\n";
}
sub wanted {
return unless (-f && /^file/);
my $mod = -M $_;
if (!defined($times{$File::Find::dir}) or
$mod < $times{$File::Find::dir}{mod}) {
$times{$File::Find::dir}{mod} = $mod;
$times{$File::Find::dir}{file} = $File::Find::name;
}
}
如果我在我的测试目录中运行此命令,在我的系统上,我会得到以下Data::Dumper
结构,您可以在其中清楚地看到文件名密钥,file
密钥中存储的完整路径,以及修改日期(与脚本运行时间相比的天数)为mod
。
$VAR1 = {
'./phone' => {
'file' => './phone/file.txt',
'mod' => '3.47222222222222e-005'
},
'./foo' => {
'file' => './foo/fileb.txt',
'mod' => '0.185'
},
'.' => {
'file' => './file.conf',
'mod' => '0.154490740740741'
}
};
答案 1 :(得分:1)
我能想到3种一般方法。
最合适的选择取决于您拥有的具体内容 使用,我们无法从您的帖子中看到。
另外,我假设当你说“没有外部模块”时,你不是 排除使用Perl安装的模块(即在Core中)。
以下是使用glob()的示例:
use File::Basename qw/fileparse/;
for my $file (newest_file()) {
print "$file\n";
}
sub newest_file {
my %files;
for my $file (glob('./path/stuff*/file*')) {
my ($name, $path, $suffix) = fileparse($file);
my $mtime = (stat($file))[9];
if (!exists $files{$path} || $mtime > $files{$path}[0]) {
$files{$path} = [$mtime, $name];
}
}
return map { $files{$_}[1] } keys %files;
}