Perl - 通过在写入之前检查打开的文件中是否已存在模式来防止重复

时间:2014-02-18 01:01:05

标签: perl duplicates duplicate-removal

我有一个perl脚本,可以管理特定文件格式转换为我以后可以管理的csv文件。

我需要此脚本才能防止生成重复的行:

  #get timetamp
  if ((rindex $l,"ZZZZ,") > -1) {
          (my $t1, my $t2, my $timestamptmp1, my $timestamptmp2) = split(",",$l);
          $timestamp = $timestamptmp2." ".$timestamptmp1;
  }

  if (((rindex $l,"TOP,") > -1) && (length($timestamp) > 0)) {
    (my @top) = split(",",$l);
        my $aecrire = $SerialNumber.",".$hostnameT.",".$timestamp.",".$virtual_cpus.",".$logical_cpus.",".$smt_threads.",".$top[1];
        my $i = 3;###########################################################################
        while ($i <= $#top) {
      $aecrire = $aecrire.','.$top[$i];
          $i = $i + 1;
        }
        print (FIC2 $aecrire."\n");
  }

我的源文件是FIC1和目标文件FIC2,uniq键是$ timestamp。

我希望脚本检查FIC1中是否已经存在$ timestamp(在进程开始时打开),如果它确实排除了写入FIC2的行。 如果$ timestamp不存在,则写为正常。

目前,如果在已经继续执行的文件上重新运行脚本,则每行将按时间戳排序并重复。

我的目标是能够在文件上定期运行此脚本而不会重复事件。

我对perl很新,据我所知,这应该只是在while中使用%see变量来实现,但我还没有成功实现它......

非常感谢您提前寻求帮助: - )

2 个答案:

答案 0 :(得分:1)

你所描述的是哈希。

您可以在代码中定义哈希

my %seen = ();

然后,当你读到一行时 - 在你决定写它之前,你可以做类似的事情:

#Check the hash to see if we have seen this line before we write it out

if ($seen{$aecrire} eq 1) {
 #Do nothing - skip the line
} else {
 $seen{$aecrire} = 1;  
 print (FIC2 $aecrire."\n"); 
}

我没有检查过这段代码,但这就是jist。

答案 1 :(得分:0)

我最后在流程结束时添加了以下代码:

my (@final, %hash, $file) = ((), (), "");

foreach $file ($dstfile_CPU_ALL, $dstfile_MEM, $dstfile_VM, $dstfile_PROC, $dstfile_TOP ) {

        if (!open FILE, "+<$file") {
                print "Nothing to dedup, '$file' $!\n";
                next;
        }

        while (<FILE>) {
                if (not exists $hash{$_}) {
                        push @final, $_;
                        $hash{$_} = 1;
                }
        }

        truncate FILE, 0;
        seek FILE, 0, 0;
        print FILE @final;
        close FILE;
        %hash = @final = ();
}