Perl - Reading .txt files line-by-line and using compare function (printing non-matches only once)

Posted by Kurt W on Stack Overflow See other posts from Stack Overflow or by Kurt W
Published on 2014-08-21T15:58:30Z Indexed on 2014/08/21 16:20 UTC
Read the original article Hit count: 144

Filed under:
|
|

I am really struggling and have spent about two full days on this banging my head against receiving the same result every time I run this perl script.

I have a Perl script that connects to a vendor tool and stores data for ~26 different elements within @data. There is a foreach loop for @data that breaks the 26 elements into $e->{'element1'), $e->{'element2'), $e->{'element3'), $e->{'element4'), etc. etc. etc.

I am also reading from the .txt files within a directory (line-by-line) and comparing the server names that exist within the text files with what exists in $e->{'element4'}.

The Problem:

Matches are working perfectly and only printing one line for each of the 26 elements when there is a match, however non-matches are producing one line for every entry within the .txt files (37 in all). So if there are 100 entries (each entry having 26 elements) stored within @data, then there are 100 x 37 entries being printed.

So for every non-match in the: if ($e->{'element4'} eq '6' && $_ =~ /$e->{element7}/i) statement below, I am receiving a print out saying that there is not a match. 37 entries for the same identical 26 elements (because there are 37 total entries in all of the .txt files).

The Goal:

I need to print out only 1 line for each unique entry (a unique entry being $e->{element1} thru $e->{element26}). It is already printing one 1 line for matches, but it is printing out 37 entries when there is not a match. I need to treat matches and non-matches differently.

Code:

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)'

I think I need something to identical unique elements and define what fields make up a unique element but honestly I have tried everything I know. If you would be so kind to provide actual code fixes, that would be wonderful because I am headed to production with this script quite soon. Also. I am looking for code (ideally) that is very human-readable because I will need to document it so others can understand.

Please let me know if you need additional information.

© Stack Overflow or respective owner

Related posts about perl

Related posts about unique