Perl: sorting files by whats in'em

i'm halfway into my script and realize i may need to use an associative array (a hash, i guess they are called in Perl). i'm fairly new to Perl and don't know how to use them correctly.

i have some files in a directory. each file contains a number in a specific place in it's header. what i would like to do is create a list of the files in a text file that has them sorted according to this number. there is also one other thing. some of the files' numbers "overlap" and i don't want these files included. since this is kind of weird to explain i'll use the following example:

below is the list of files along with their associated numbers before they are sorted. notice at "file12" the numbers start overlapping and starting with "file21" the numbers reach the point past -0.5 (which is file11's number). i basically do not want files 12 through 20 included in my text file.

"file1",-30.5
"file2",-27.5
"file3",-24.5
"file4",-21.5
"file5",-18.5
"file6",-15.5
"file7",-12.5
"file8",-9.5
"file9",-6.5
"file10",-3.5
"file11",-0.5
"file12",-26.5
"file13",-23.5
"file14",-20.5
"file15",-17.5
"file16",-14.5
"file17",-11.5
"file18",-8.5
"file19",-5.5
"file20",-2.5
"file21",0.5
"file22",3.5
"file23",6.5
"file24",9.5
"file25",12.5
"file26",15.5
"file27",18.5
"file28",21.5
"file29",24.5
"file30",27.5
"file31",30.5

here is the way the text file with the sorting should look:

"file1",-30.5
"file2",-27.5
"file3",-24.5
"file4",-21.5
"file5",-18.5
"file6",-15.5
"file7",-12.5
"file8",-9.5
"file9",-6.5
"file10",-3.5
"file11",-0.5
"file21",0.5
"file22",3.5
"file23",6.5
"file24",9.5
"file25",12.5
"file26",15.5
"file27",18.5
"file28",21.5
"file29",24.5
"file30",27.5
"file31",30.5

Note: the quotes aren't part of the file names and the file names for the files are not named so that you can "deduce" the order (file1 -> file31), they are for all intents and purposes random. Also, i know the numbers increase by 3 (and that is how they increase), but the gap in between the cut off is only 1 (from -0.5 to 0.5), and this is ok. i basically cannot have a gap more than 3.

what i'm thinking is that an associative array may be appropriate, but i'm not sure. my logic so far has been to first, find the smallest number and write it's corresponding filename to the text file. then find the filename with the first file's number + 3, and append that filename to the textfile. then, if no more files fit that criteria, start appending the filenames by which is larger than the last one. i think this would work but i don't know how to do it.

thanks in advance for helping. this will save me lots of time, since i have many directories like this and sorting them by hand takes a long time.

Your task is composed of two subtasks:
1) Extracting all ($filename, $magic_number) pairs from all files to create a temporary list.
2) Sorting and scanning the list generated and picking the right entries.

For (1) it is assumed you know how to do it. A hash is not the right data structure to sort keys according to values. Arrays is my favourite. You can set up an array containing the pairs like this:

# ... set up a loop to run through all files
push @array, [$filename, $magic_number];
# loop ends here

As for (2) you can then sort the pairs ascendingly by

@sorted = sort { $$a[1] <=> $$b[1] } @array;

my $counter = $sorted[0]->[1];
# Before the gap
foreach (@sorted) {
if ($counter == $->[1]) {
push @finallist, $
;
$counter += 3;
}
}

# After the gap
foreach (@sorted) {
if ($->[1] > $counter-3) {
push @finallist, $
;
}
}

#print result
foreach (@finallist) {
# Print filename and magic number
print $->[0], ", ", $->[1], "\n";
}

Warning: untested code.

Your explanation of "overlap" is a bit confusing. By throwing out your "overlapping" numbers, you are already assuming that your numbers are mostly sorted descending. Explain what you are trying to do here. It seems like there is more behind your question than just sorting. You are eliminating numbers based on a special criteria.

#! /usr/local/bin/perl -w

@array = (qw /-20 -17 -14 -11 -8 -5 -2 -6 -3 0 3 6 9 12 15 18/);
# i want 18 15 12 9 6 3 0 -2 -5 -8 -11 -14 -17 -20
# because i can't have intervals greater than 3
# AND i can have only one interval less than 3

# We'll need the list of numbers as a string separated by spaces
foreach (@array) {
$num_string .= $_ . " ";
}

print "$num_string\n";

$pre_num = 10000; # Shirley, they'll never be a number more than 10000...right?
$count = 0;
$less_than_counter = 1;
foreach $num (sort {$b<=>$a} @array) {
$count ++;
if (($num == ($pre_num-3)) || ($count == 1)) { # It's a keeper!
print "$num\n";
$pre_num = $num;
}
elsif ($num < ($pre_num-3)) { # Detects if increment is more than 3
die "A number is missing!!!\n";
}
elsif (($num > ($pre_num-3)) && ($less_than_counter == 1)) { # Detects if increment is less than 3, allows it once
print "$num\n";
$less_than_counter ++;
$pre_num = $num;
}
else {
# do nothing
}
}

is it really so difficult

sort -n -t, -k2 file1

is this not what you are looking for.
correct me if i have misunderstood