2016-07-07 123 views
2

我在目录中有以下文件,其中定界符是“_”,第三个字段是创建文件的日期。 现在我需要始终根据第一列代码选择具有最早日期的文件。按日期返回旧文件

例子:

1020300000_XXXXXXXXX_20160707193000.TXT 
1020300000_XXXXXXXXX_20160707170000.TXT 
1020400000_XXXXXXXXX_20160707180000.TXT 
1020400000_XXXXXXXXX_20160707190000.TXT 

在这种情况下,我需要有一个结果,旧文件。

1020300000_XXXXXXXXX_20160707170000.TXT 
1020400000_XXXXXXXXX_20160707180000.TXT 

有人可以帮助我只返回旧文件吗?

+3

为什么'1020300000_XXXXXXXXX_20160707193000.TXT'早于'1020300000_XXXXXXXXX_20160707170000.TXT'?目录列表是否已按日期排序?不是最后的6位数字HHMMSS? –

+0

是的,就是这样。 –

+2

@LeonardoBerbert - 请回答卡西米尔的问题 – Arijit

回答

-1

我假设你的输出应该是

1020300000_XXXXXXXXX_20160707170000.TXT 
1020400000_XXXXXXXXX_20160707180000.TXT 

。如果不是,我不知道你的要求是什么。无论如何,我希望这是你需要

#!/usr/bin/perl 

use Data::Dumper; 

# folder saves the files 
$folder = "test"; 

# save file names as array 
@files = `ls $folder`; 
chomp @files; 

foreach $file (@files){ 
     #split filename to 3 columns e.g. 
     #1020300000 XXXXXXXXX 20160707170000.TXT 
     ($col_1, $col_2, $col_3) = split(/_/, $file); 

     #delete .TXT 
     $col_3 =~ s/\.txt$//i; 

     #use my to create new @tmp every loop 
     my @tmp = ($col_3, $file); 

     #%outpput is our target result 
     #col_1 is key, the hash should look like this 
     # '1020300000' => [ 
     #     '20160707170000', <= this is col_3, will be used to compare later 
     #     '1020300000_XXXXXXXXX_20160707170000.TXT' <= condidate of the result 
     #     ] 
     unless(defined $output{$col_1}){ 
       $output{$col_1} = \@tmp; 
       next; 
     }; 

     $saved_col_3 = $output{$col_1}->[0]; 

     #because $col_1 are the same (key), so compare their col_3 value 
     if($col_3 < $saved_col_3){ 
       #update if this one is smaller 
       $output{$col_1} = \@tmp; 
     } 
} 

#print Dumper(\%output); 

#so.... 
foreach (keys %output){ 
     print "$output{$_}->[1]\n"; 
} 
0

您可以利用的事实的日期是在YYYYMMDDHHMISS,只是对它们进行排序,并使用散列只得到顶部值,返回你所需要的项目是什么:

sub get_oldest_two { 
    my (@files) = @_; 

    my @sorted = sort { [split(/_/, $a)]->[2] lt [split(/_/, $b)]->[2] } @files; 
    my %file_dates = map { [split(/_/, $_)]->[0] => $_ } @sorted; 
    return reverse(sort((values(%file_dates))[0..1])); 
} 
1

你可以这样来做:

use strict; 
use warnings; 
use feature qw(say); 

my $path = "./yourdir"; 
opendir (my $dh, $path) || die "Can't opendir $path: $!"; 

my @filelist = grep { -f "$path/$_" } readdir $dh; 

my @result = sort values {  # (4) 
    map +($_->[1], $_->[0]), # (3) 
    sort { $b->[2] cmp $a->[2] } # (2) 
    map [ $_, (split '_')[0,2] ], # (1) 
@filelist 
}; 

say join "\n", @result; 

(1)返回引用的列表,以匿名的三个元素的数组:
([文件名,firstpart,thirdpart],[文件名,firstpart,thirdpart],...)

(2)降序返回一个排序列表(从最新到最旧)使用创建日期(第三方)。

(3)返回由所述 “firstpart”,并从输入列表中引用的每个阵列 “文件名” 的列表:
(firstpart,文件名,firstpart,文件名,.. )

(4)使用列表创建一个匿名散列(此处大括号不会分隔块或表达式,但定义散列)。所有第一部分s成为关键字,所有文件名s的值。 由于文件名先前是从最新到最旧排序的,因此每个关键字都与最早的文件名相关联,该文件名将覆盖最后一个相同关键字的最新值。