2011-02-16 43 views
1

我有这样的代码,其中列出在我的目录中的所有文件:我如何知道阵列中是否有类似的元素?

$dir = '/var/www/corpIDD/rawFile/'; 
opendir DIR, $dir or die "cannot open dir $dir: $!"; 
my @file= readdir DIR; 
closedir DIR; 

返回包含像这样的数组:

$array (0 => 'ipax3_2011_01_27.txt', 1 => 'ipax3_2011_02_01.txt', 2 => 'ipax3_2011_02_03.txt') 

我的问题在这里,我将如何存储单元1 => 'ipax3_2011_02_01.txt'和2 =>'ipax3_2011_02_03.txt'分隔变量,因为它们属于同一个月份和年份(2011_02)?

谢谢!

+0

我试过了:#在数组元素中搜索模式“year_month”;# $ search = $ year。“_”。$ this_month; @match = grep(/ $ search/i,@file); 但这只会查找当前月份的任何文件。我需要在我的目录中查找任何具有两个或更多条目的文件。 – 2011-02-16 01:45:33

回答

3

在Perl中,当您需要使用字符串作为数据结构中的键时,您正在寻找HASH内置类型,由% sigil指定。 Perl散列的一个很好的特性是你不必预先声明一个复杂的数据结构。你可以使用它,Perl会根据这种用法推断出结构。

my @file = qw(ipax3_2011_01_27.txt ipax3_2011_02_01.txt ipax3_2011_02_03.txt); 

my %ipax3; 

for (@file) { 
    if (/^ipax3_(\d{4}_\d{2})_(\d{2}).txt$/) { 
     $ipax3{$1}{$2} = $_ 
    } 
    else { 
     warn "bad file: $_\n" 
    } 
} 

for my $year_month (keys %ipax3) { 
    my $days = keys %{ $ipax3{$year_month} }; 
    if ($days > 1) { 
     print "$year_month has $days files\n"; 
    } 
    else { 
     print "$year_month has 1 file\n"; 
    } 
} 

它打印:

 
2011_01 has 1 file 
2011_02 has 2 files 

要获取单个文件:

my $year_month = '2011_02'; 
my $day  = '01'; 
my $file  = $ipax3{$year_month}{$day}; 

上面我用了keys既充当列表的返回值来遍历和作为天数。这是可能的,因为keys将返回列表上下文中的所有键,并且将返回标量上下文中的键数。上下文是由周围的代码提供:

my $number = keys %ipax3; # number of year_month entries 

my @keys = keys %ipax3; # contains ('2011_01', '2011_02') 

my @days = keys %{ $ipax{$year_month} }; 

在最后一个例子中,每个%ipax值是散列的引用。由于keys需要字面散列,因此您需要将$ipax{$year_month}换算为%{ ... }。在perl v5.13.7 +中,你可以省略参数%{ ... }keys以及其他一些数据结构访问函数。

+0

哇!这太棒了!我是一个新手perl,这就是为什么我不知道这些功能。非常感谢你。 – 2011-02-16 02:20:23

1

人们在这里反应非常快:)无论如何,我会发布我的,仅供您参考。基本上,我也使用散列。

use warnings qw(all); 
use strict; 

my ($dir, $hdir) = 'C:\Work'; 
opendir($hdir, $dir) || die "Can't open dir \"$dir\" because $!\n"; 
my (@files) = readdir($hdir); 
closedir($hdir); 

my %yearmonths; 
foreach(@files) 
{ 
    my ($year, $month); 
    next unless(($year, $month) = ($_ =~ /ipax3_(\d{4})_(\d{2})/)); 
    $year += 0; 
    --$month;   #assuming that months are in range 1-12 
    my $key = ($year * 12) + $month; 
    ++$yearmonths{ $key }; 
} 
foreach(keys %yearmonths) 
{ 
    next if($yearmonths{ $_ } < 2); 
    my $year = $_/12; 
    my $month = 1 + ($_ % 12); 
    printf "There were %d files from year %d, month %d\n", $yearmonths{$_}, $year, $month; 
} 
+0

谢谢!那些也很棒! – 2011-02-16 02:33:43

相关问题