第一次海报和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;
}
}
答案 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
}