Maybe I'm being dense, but why are you reading sections of the file more than once anyway? You only need to read from where you are and below as I read your node. This is usually done by setting some sort of flag value and testing that flag. Your I/O system will thank you.

The following code produces very close to your expected output from your sample input. There may be an extraneous newline at the end if you care about that. I've heavily commented this to make it easier to follow. I also threw in some quite simple debugging for the data structure and made the regex a bit easier (for me) to read.

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; # added for debugging the hash my $DEBUG = 0; # enable debugging if true my $file = 'tmpfile'; my $numelements; my %connection; # This becomes the central data structure. Called it + 'connection' because it represents a typical TCP connection open my $info, '<', $file or die "Could not open $file: $!"; # favor t +hree-argument open when you're not using open's magic # Read all the info in a single pass by use of a start flag, put it in + the data structure. while ( my $line = <$info> ) { if ( $line =~ m/(src=(?:\d+\.){3}\d+ dst=(?:\d+\.){3}\d+ src_port= +\d+ dst_port=\d+) reason=(.*)/ ) { # capture the reason my $match = $1; if ( $2 eq 'AGE OUT' ) { # test to see if the reason is what w +e're looking for at the start $connection{ $match }{ 'aged_out' } = 1; } if ( exists $connection{ $match } and $connection{ $match }{ ' +aged_out' } ) { # If we've recieved an 'AGE OUT' reason, then $connection{ + $match }{ 'aged_out' } has been autovivified and we can start counti +ng and pushing. # Keep track of this and following lines for this connecti +on in this sub-hash. $connection{ $match }{ 'count' }++; push @{ $connection{ $match }{ 'line' } }, $line; # The ac +tual lines are in a HoHoA here. } } } close $info; print Dumper %connection if $DEBUG; # Now there's a data structure from the above loop we can loop over wi +thout accessing the file any longer. for my $con ( keys %connection ) { print "$con has " . $connection{ $con }{ 'count' } . " elements\n" +; if ( $connection{ $con }{ 'count' } > 1 ) { print @{ $connection{ $con }{ 'line' } }; # Doesn't need to be + joined because the newlines were never stripped. } print "\n"; }

In reply to Re: Define string on current line, then match other lines with string below the line by mr_mischief
in thread Define string on current line, then match other lines with string below the line by Mashed Potato

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.