有没有更好的方法可以用Perl从文件中提取重复的字符串



我目前正在循环浏览一个日志文件,提取某些特征。我必须检查一个唯一的字符串是否重复,如果字符串重复,则忽略该日志。目前,我的代码需要花费大量的时间来运行(或者我处于无限循环中)yippey。有没有更好的方法从文件中提取重复项并检查其唯一性?

close($handle);
$test = "testFile.txt";
open( $handle, '<', $domainAnalysis ) or die "Cannot open file: $!";
open( $hand,   '>', $test )           or die "Cannot open file: $!";
my %uniq;
while ( $search = <$handle> ) {
    if ( $search =~ /Mail ID: ([^:]*)n/g ) {
        $uniq{$search}++;
    }
    my @sortedHash = sort keys %uniq;
    foreach $i (@sortedHash) {
        if ( $i eq $search ) {
            print $hand $search;
            print $hand scalar <$handle> for 1 .. 2;
        }
    }
}

如有任何帮助,我们将不胜感激。我有点被卡住了。

编辑:

它目前正在读取一个日志文件,并将所需信息拉到一个新文件中。新文件以该的格式打印

Mail ID: b12342534  
Domain : someEmail@email.com  
Status Message = Sent  
Mail ID: a32432234  
Domain : someEmail@email.com  
Status Message = Deferred  

输出:程序实际上从未停止。这需要很长时间,我的耐心不会让它一直持续下去。

我很确定你的问题是内部循环——当你迭代日志时,可能会积累大量的"邮件ID"条目。

在每个循环中,对它们进行排序,然后对它们进行迭代并进行比较。

更重要的是,你在每个散列中插入的$search是each LINE,这意味着它将变得巨大。

不管怎样,我建议考虑到你的输入数据,首先你使用$/:

local $/ = ''; #read in paragraph mode.  
my %seen; 
while ( <$input> ) { 
    my ( $id ) = m/Mail ID: ([^:]*)/;
    print unless $seen{$id}++; 
}

这将只在第一次发现特定的邮件ID时打印。

(当然,如果您只想打印重复项,您可以使用"if"而不是"除非")

首先,不需要迭代哈希的所有键;它打破了散列的全部要点

假设你想要数组@arr的元素$arr[3],你会写这个吗?

for my $i ( 0 .. $#arr ) {
    if ( $i == 3 ) {
        print "Found: $arr[$i]n";
    }
}

因此您可以使用$uniq{$search} 访问%uniq的任何先前存在的元素

其次,当您递增时,您可以简单地测试%uniq的元素当前是否为零

像这个

my $test           = 'testFile.txt';
my $domainAnalysis = '...';
open my $handle, '<', $domainAnalysis or die qq{Cannot open "$domainAnalysis": $!};
open my $hand,   '>', $test           or die qq{Cannot open "$test": $!};
my %uniq;
while ( my $search = <$handle> ) {
    next unless $search =~ /^Mail ID:/;
    if ( $uniq{$search}++ ) {
        print $hand $search;
        print $hand scalar <$handle> for 1 .. 2;
    }
}

您还必须始终use strictuse warnings 'all',并使用my声明所有变量,使其尽可能接近首次使用的位置

对于文件句柄来说,$hand$handle是可怕的名称!

相关内容

  • 没有找到相关文章

最新更新