首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Perl -逐行读取.txt文件并使用比较函数(只打印一次不匹配)

Perl -逐行读取.txt文件并使用比较函数(只打印一次不匹配)
EN

Stack Overflow用户
提问于 2014-08-21 15:58:30
回答 2查看 946关注 0票数 0

我真的很挣扎,每次我运行这个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条条目。我需要区别对待火柴和非火柴。

代码:

代码语言:javascript
复制
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)'

我想我需要一些东西来相同的,独特的元素,并定义什么字段构成一个独特的元素,但老实说,我已经尝试了我知道的一切。如果您能很好地提供实际的代码修复,那就太好了,因为我很快就要使用这个脚本进行生产了。还有。我正在寻找非常具有人类可读性的代码(理想情况下),因为我需要记录它,以便其他人能够理解。

如果你需要更多的信息,请告诉我。

EN

回答 2

Stack Overflow用户

发布于 2014-08-21 16:32:43

就我个人而言,我会将所有坏节点都推到数组中,然后用List::MoreUtils提取我想要的内容。此外,一个样本的结果也可能是有益的。

代码语言:javascript
复制
# 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;
    }
}
票数 0
EN

Stack Overflow用户

发布于 2014-08-21 16:44:18

您正在测试某一行是否与“元素7”匹配,以及是否匹配--打印所有元素。它不匹配,你似乎也在做同样的事情?

你想在那个else代码库里做什么?

我会冒险猜一猜,你可能想尝试的是:

代码语言:javascript
复制
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";   
}

还是我错过了你想要实现的目标?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25430818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档