我目前正在循环显示某些特征的日志文件。如果它是重复的,我必须检查一个唯一的字符串,如果该字符串是重复的,则忽略该日志。目前,我的代码需要花费大量的时间来运行(或者我在无限循环中)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
输出:好,程序永远不会停止。它需要永远,我的耐心不会让它一直运行。
答案 0 :(得分:2)
我很确定你的问题是内循环 - 当你迭代日志时,可能你会积累大量的'邮件ID'条目。
每个循环,你将它们全部排序,然后迭代它们并比较它们。
而且 - 更重要的是 - 你在每个哈希中插入的$search
是EACH LINE,这意味着它会变得越来越大。
无论如何 - 我建议您提供输入数据,首先使用$/
:
local $/ = ''; #read in paragraph mode.
my %seen;
while ( <$input> ) {
my ( $id ) = m/Mail ID: ([^:]*)/;
print unless $seen{$id}++;
}
这将仅在第一次发现特定邮件ID时打印。
(当然,如果您只想打印重复,您可以使用'if'而不是'除非')
答案 1 :(得分:1)
首先,没有必要迭代哈希的所有键;它打破了哈希的整个点
假设你想要arra $arr[3]
的元素@arr
,你会写这个吗?
for my $i ( 0 .. $#arr ) {
if ( $i == 3 ) {
print "Found: $arr[$i]\n";
}
}
因此您可以使用%uniq
$uniq{$search}
元素
其次,您可以简单地测试%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 strict
和use warnings 'all'
并声明所有变量my
尽可能接近首次使用的位置
$hand
和$handle
是文件句柄的可怕名称!