#!/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 three-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 we'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 counting and pushing. # Keep track of this and following lines for this connection in this sub-hash. $connection{ $match }{ 'count' }++; push @{ $connection{ $match }{ 'line' } }, $line; # The actual 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 without 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"; }