my( $first, $lastTag ) = ( 0, '' ); OUTER: while( ) { chomp; ## ((simplified for testing) my( $atag, $astart, $aend, $mess ) = split "\t"; ## If the tag changed, reset the start position for the Main records ## and remember the new tag $first = 0, $lastTag = $atag if $atag ne $lastTag; ## Skip completely if this Annot tag has no corresponding Main tag next unless exists $main{ $atag }; ## For each Main record with this tag, ## But skipping those we rejected last time for my $md ( @{ $main{ $atag } }[ $first .. $#{ $main{ $atag } } ] ) { ## (simplified for testing) my( $mtag, $mstart, $mend ) = split "\t", $md; ## Increment the skip and goto the next Main record ## If the end of this Main record is less than ## the start of the Annot record ++$first, next if $mend < $astart; ## Skip the rest of these Main record ## if the start of this Main record is greater than ## the end of this Annot record next OUTER if $mstart > $aend; ## We have an overlap, so output the info print OUTPUT "$atag\t$mess"; } }