use strict; use warnings; use constant { LOW => 0, HIGH => 1, VALUE => 2 }; my $FILE1 = <<'EOF'; so 10 0.05 so 11 0.03 so 25 0.15 so 35 0.3 so 36 0.25 so 37 1 ge 14 0.12 ge 20 0.4 EOF my $FILE2 = <<'EOF'; so 10 20 so 30 40 ge 10 30 EOF my %ranges; # Read FILE2 and create a useful datastructure. open my $ifh2, '<', \$FILE2 or die $!; while( <$ifh2> ) { chomp; next unless length; my( $cat, $low, $high ) = split /\s+/, $_; push @{$ranges{$cat}}, [ $low, $high ]; } close $ifh2; # Read FILE1 and increment counters within our datastructure. open my $ifh1, '<', \$FILE1 or die $!; while( <$ifh1> ) { chomp; next unless length; my( $cat, $target, $value ) = split /\s+/, $_; foreach my $range ( @{$ranges{$cat}} ) { $range->[VALUE] += $value if $target >= $range->[LOW] && $target <= $range->[HIGH]; } } # Dump the information we need from our datastructure. while( my( $cat, $range ) = each %ranges ) { print "$cat $_->[VALUE]\n" foreach @$range; } #### %ranges = ( 'ge' => [ [ 10, 30, '0.52' ] ], 'so' => [ [ 10, 20, '0.08' ], [ 30, 40, '1.55' ] ] ); #### so 0.08 so 1.55 ge 0.52