in reply to filtering data and while loop problem

You don't quite have for (...) { while (<DATA>) { } }, but you do suffer from the same problem (in addition to the one samarzone mentioned). If the first pass of the loop reads DATA until its end of file, what do you think the next pass of the loop will read?

You should be loading the contents of DATA into a memory structure, and extracting the data you need from the data structure for each triple.

use strict; use warnings; my %data; { my $chrom; while (<DATA>) { chomp; if (/^variableStep chrom=(\S+)/) { $chrom = $1; } else { my ($tag, $value) = split; push @{ $data{$chrom} }, [ $tag, $value ]; } } } for ( [qw( chr1 9837 9840 )], [qw( chr1 99998 99999 )], [qw( chr2 9838 9840 )], ) { my ($chrom, $start, $stop) = @$_; my $chrom_d = $data{$chrom}; my $count; my $sum; for (@$chrom_d) { my ($tag, $value) = @$_; next if $tag < $start || $tag > $stop; ++$count; $sum += $value; } if ($count) { my $avg = $sum/$count; print("$chrom $start..$stop average: $avg\n"); } else { print("$chrom $start..$stop average: NA\n"); } } __DATA__ variableStep chrom=chr1 9837 0.010 9838 0.008 9839 0.007 9840 0.004 9841 0.002 9842 0.001 variableStep chrom=chr2 9837 0.090 9838 0.038 9839 0.017 9840 0.044 9841 0.052 9842 0.091
chr1 9837..9840 average: 0.00725 chr1 99998..99999 average: NA chr2 9838..9840 average: 0.033