Foreach循环内的动态数组

时间:2013-12-18 22:58:47

标签: perl

第一次海报和Perl的新手,所以我有点卡住了。我正在迭代一组长文件名,其中的列由可变数量的空格分隔,例如:

0     19933     12/18/2013 18:00:12  filename1.someextention
1     11912     12/17/2013 18:00:12  filename2.someextention
2     19236     12/16/2013 18:00:12  filename3.someextention

这些是由多个服务器生成的,所以我正在迭代多个集合。这种机制很简单。

我只专注于日期列,需要确保日期如上例所示,因为这样可以确保每天创建文件并且只创建一次。如果文件每天创建多次,我需要做一些事情,例如向自己发送电子邮件,然后转到下一个服务器集合。如果日期从第一个文件更改为第二个文件也退出循环。

我的问题是我不知道如何保存第一个文件的日期元素,以便我可以将它与下一个文件的循环日期进行比较。我想保持元素存储在循环内的数组中,直到当前集合完成,然后移动到下一个集合,但我不知道这样做的正确方法。任何帮助将不胜感激。此外,如果有更有说服力的方式,请告诉我,因为我愿意学习,而不仅仅是想让别人为我编写脚本。

@file = `command -h server -secFilePath $secFilePath analyzer -archive -list`;
@array = reverse(@file); # The output from the above command lists the oldest file first 

    foreach $item (@array) {
    @first = split (/ +/, @item);
    @firstvar = @first[2];
#if there is a way to save the first date in the @firstvar array and keep it until the date
 changes       
    if @firstvar == @first[2] { # This part isnt designed correctly I know.                }
            elsif @firstvar ne @first[2]; {
            last;
            }
}

1 个答案:

答案 0 :(得分:3)

一种常见的技术是使用hash,它是映射键值对的数据结构。如果您按日期键入,则可以检查之前是否遇到过给定日期。

如果没有遇到日期,则哈希中没有密钥。

如果遇到日期,我们在该键下插入1来标记它。

my %dates;
foreach my $line (@array) {
    my ($idx, $id, $date, $time, $filename) = split(/\s+/, $line);

    if ($dates{$date}) {
        #handle duplicate
    } else {
        $dates{$date} = 1;

        #...
        #code here will be executed only if the entry's date is unique
    }

    #...
    #code here will be executed for each entry
}

请注意,这将检查每个日期与其他日期。如果由于某种原因你只想检查两个相邻日期是否匹配,你可以只缓存最后一个$date并检查它。


在评论中,OP提到他们可能宁愿执行我提到的第二次检查。它很相似。可能看起来像这样:

#we declare the variable OUTSIDE of the loop
#if needs to be, so that it stays in scope between runs
my $last_date;
foreach my $line (@array) {
    my ($idx, $id, $date, $time, $filename) = split(/\s+/, $line);

    if ($date eq $last_date) { #we use 'eq' for string comparison
        #handle duplicate
    } else {
        $last_date = $date;

        #...
        #code here will be executed only if the entry's date is unique
    }

    #...
    #code here will be executed for each entry
}