我有以下文件列表:
INV_1400524_20170412_052945.pdf
INV_1400524_20170412_063522.pdf
INV_1400524_20170412_090338.pdf
INV_1400524_20170412_092911.pdf
INV_1400971_20170502_095250.pdf
INV_1401580_20170703_100410.pdf
INV_1401880_20170804_112917.pdf
RIN_1300355_20170503_014347.pdf
RIN_1300552_20170518_111143.pdf
RIN_1300552_20170518_122055.pdf
RIN_1300688_20170627_040340.pdf
RIN_1300834_20170727_113641.pdf
RIN_1300834_20170727_154404.pdf
格式为:
<Document Type>_<Document Number>_<Date>_<Time>.pdf
如您所见,由于某种原因,多次输出相同的文档编号。我想忽略重复项并将列表过滤到唯一的文档编号和最新日期。这些文档还有一个修改过的文件时间戳,如果有帮助,它会与文件名中的日期和时间紧密匹配。
使用perl(我一直在使用File :: Find :: Rule)我想将列表缩减为:
INV_1400524_20170412_092911.pdf
INV_1400971_20170502_095250.pdf
INV_1401580_20170703_100410.pdf
INV_1401880_20170804_112917.pdf
RIN_1300355_20170503_014347.pdf
RIN_1300552_20170518_122055.pdf
RIN_1300688_20170627_040340.pdf
RIN_1300834_20170727_154404.pdf
我已经开始了
my @pdf_files = File::Find::Rule->new
->in($root_dir)
->name( '*.pdf' )
->mtime (">$days_ago");
但是看看这个答案: How can I find the newest .pl file in a directory and all its subdirectories using Perl?
我认为可能有一种使用方法:
my $rule = File::Find::Rule->new;
$rule->or( $rule->new->name('INV_*.pdf')->....
$rule->or( $rule->new->name('RIN_*.pdf')->....
my @files = $rule->in($root_dir);
将它们分组并过滤掉。有什么想法吗?
答案 0 :(得分:1)
使用grep
:
my %seen;
my @files = grep { not $seen{$_}++ } @files;
因为你是增量后测试,所以第一次测试是真的,所有其他测试都是假的。你也可以使用正则表达式来匹配例如子串。文件ID:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
chomp(
my @files = <DATA>
);
my %seen;
@files = grep { m/(\d+)/ and not $seen{$1}++ } @files;
print Dumper \@files;
__DATA__
INV_1400524_20170412_052945.pdf
INV_1400524_20170412_063522.pdf
INV_1400524_20170412_090338.pdf
INV_1400524_20170412_092911.pdf
INV_1400971_20170502_095250.pdf
INV_1401580_20170703_100410.pdf
INV_1401880_20170804_112917.pdf
RIN_1300355_20170503_014347.pdf
RIN_1300552_20170518_111143.pdf
RIN_1300552_20170518_122055.pdf
RIN_1300688_20170627_040340.pdf
RIN_1300834_20170727_113641.pdf
RIN_1300834_20170727_154404.pdf
输出:
$VAR1 = [
'INV_1400524_20170412_052945.pdf',
'INV_1400971_20170502_095250.pdf',
'INV_1401580_20170703_100410.pdf',
'INV_1401880_20170804_112917.pdf',
'RIN_1300355_20170503_014347.pdf',
'RIN_1300552_20170518_111143.pdf',
'RIN_1300688_20170627_040340.pdf',
'RIN_1300834_20170727_113641.pdf'
];
如果您的标准更加合理,那么您可能需要应用排序以确保“首先”。过滤到顶部。
有两种方法 - 你可以sort
使用文件名 - 而且因为你有一个ISO日期,看起来它会起作用:
@files = grep { m/(\d+)/ and not $seen{$1}++ } sort @files;
或者你可以根据stat
系统调用进行某种排序(为此你需要完整的文件路径,所以要注意!)
@files = grep { m/(\d+)/ and not $seen{$1}++} sort { -M $a <=> -M $b } @files;
-M
是用于检查文件年龄(以天为单位)的perl filetest。
但您可以使用stat
代替。