我真的很挣扎,每次我运行这个perl脚本的时候,我都花了整整两天的时间来反对接收相同的结果。
我有一个Perl脚本,它连接到供应商工具,并在@ data 中存储26个不同元素的数据。@data有一个foreach循环,它将26个元素分解为$e->{'element1')、$e->{'element2')、$e->{'element3')、$e->{‘element4’等等。
我还从目录(逐行)中读取.txt文件,并将文本文件中存在的服务器名称与.txt中的服务器名称进行比较。
问题:
匹配是完美的,只有在有匹配时,为26个元素中的每个元素打印一行,但是非匹配项为.txt文件中的每个条目生成一行(总共37行)。因此,如果@data中存储了100个条目(每个条目有26个元素),那么就有100x37个条目正在打印。
因此,对于下面的语句($e->{'element4'} } eq '6‘&& $_ =~ /$e->{element7}/i)中的每一个不匹配,我将收到一个打印输出,表明没有匹配。相同的26个元素的37个条目(因为所有.txt文件中总共有37个条目)。
目标:
我只需要为每个唯一条目打印一行(唯一的条目是$e->{element1}到$e->{element26})。它已经为匹配打印了1行,但是当没有匹配时,它正在打印37条条目。我需要区别对待火柴和非火柴。
代码:
foreach my $e (@data) {
# Open the .txt files stored within $basePath and use for comparison:
opendir( DIRC, $basePath . "/" ) || die("cannot open directory");
my @files = ( readdir(DIRC) );
my @MPG_assets = grep( /(.*?).txt/, @files );
# Loop through each system name found and compare it with the data in SC for a match:
foreach (@MPG_assets) {
$filename = $_;
open( MPGFILES, $basePath . "/" . $filename ) || die "canot open the file";
while (<MPGFILES>) {
if ( $e->{'element4'} eq '6' && $_ =~ /$e->{'element7'}/i ) {
## THIS SECTION WORKS PERFECTLY AND ONLY PRINTS MATCHES WHERE $_
## (which contains the servernames (1 per line) in the .txt files)
## EQUALS $e->{'element7'}.
print $e->{'element1'} . "\n";
print $e->{'element2'} . "\n";
print $e->{'element3'} . "\n";
print $e->{'element4'} . "\n";
print $e->{'element5'} . "\n";
# ...
print $e->{'element26'} . "\n";
} else {
## **THIS SECTION DOES NOT WORK**. FOR EVERY NON-MATCH, THERE IS A
## LINE PRINTED WITH 26 IDENTICAL ELEMENTS BECAUSE ITS LOOPING THRU
## THE 37 LINES IN THE *.TXT FILES.
print $e->{'element1'} . "\n";
print $e->{'element2'} . "\n";
print $e->{'element3'} . "\n";
print $e->{'element4'} . "\n";
print $e->{'element5'} . "\n";
# ...
print $e->{'element26'} . "\n";
} # End of 'if ($e->{'element4'} eq..' statement
} # End of while loop
} # End of 'foreach(@MPG_assets)'
} # End of 'foreach my $e (@data)'我想我需要一些东西来相同的,独特的元素,并定义什么字段构成一个独特的元素,但老实说,我已经尝试了我知道的一切。如果您能很好地提供实际的代码修复,那就太好了,因为我很快就要使用这个脚本进行生产了。还有。我正在寻找非常具有人类可读性的代码(理想情况下),因为我需要记录它,以便其他人能够理解。
如果你需要更多的信息,请告诉我。
发布于 2014-08-21 16:32:43
就我个人而言,我会将所有坏节点都推到数组中,然后用List::MoreUtils提取我想要的内容。此外,一个样本的结果也可能是有益的。
# 1/2 Sudo Code
# =========================
use List::MoreUtils qw(uniq);
#...
else
{
while ( $i <= 26 ) {
push @nonMatches, $e->{'element$i++'};
}
my @badElements = uniq @nonMatches;
foreach $element ( @badElements )
{
print $element;
}
}发布于 2014-08-21 16:44:18
您正在测试某一行是否与“元素7”匹配,以及是否匹配--打印所有元素。它不匹配,你似乎也在做同样的事情?
你想在那个else代码库里做什么?
我会冒险猜一猜,你可能想尝试的是:
my %match_found_in;
my %match_found_of;
while(my $line = <MPGFILES>) {
chomp $line;
if ($e->{'element4'} eq '6' && $line =~ /$e->{'element7'}/i) {
$match_found_in{$filename} = $line;
$match_found_of{$e->{'element7'}} = $filename;
}
}
foreach my $element ( keys %match_found_of ) {
print "$element had a match in ".$match_found_of{$element},"\n";
}
foreach my $filename ( keys %match_found_in ) {
print "$filename had a match on :", $match_found_in{$filename},"\n";
}还是我错过了你想要实现的目标?
https://stackoverflow.com/questions/25430818
复制相似问题