rchou2 has asked for the wisdom of the Perl Monks concerning the following question:

sorry for the confusion.....basically i have a script that spits data into a file, and i have 3 columns...the first is a string, the second and third are numeric.....how can i sort the file based on the third column in descending order and print it into a new file? i'm new to perl, so any tips will help....

Replies are listed 'Best First'.
Re: File Sorting Rephrased
by Aristotle (Chancellor) on Jul 19, 2002 at 19:06 UTC
    You need to split the lines as you read them, then use a sort with a custom sort function.
    open FH, "<", $filename; my @record = sort { $b->[2] cmp $a->[2] } map { [ chomp; split ] } <FH +>; close FH;

    After that, you have a sorted list of records in @record.

    Update: Oh yes.. a couple mistakes there. I wasn't going for a full Transform though. :) As I said, @record contains records; not the lines from the input. Of course, a Schwartzian Transform is the simpler solution when you don't need to process the thawed data inbetween.

    Some explanation: map applies the following code block to every item from the list after it. Since we say <FH> there, the list is simply all lines of the file. The code inside the block removes the newline from the lines by way of chomp, then uses split to split the string into a list of strings. The default assumes you split on whitespace; if your field delimiters aren't blanks, you can supply different ones, see the doc. After that, the square brackets create an anonymous array and produce a reference to it. Since we did that for every line, the input to sort is going to be a list of references. Inside the sorting routine, $a and $b point to the elements to be compared; we dereference them by using the arrow operator, and pick the 3rd field from each. Then we use cmp to compare them, and because we want decending order we compare $b with $a rather than vice versa.

    Makeshifts last the longest.

Re: File Sorting Rephrased
by dug (Chaplain) on Jul 19, 2002 at 19:11 UTC
    I would reach into the toolbox for sort, and do:
    sort -n -r -k 3 file -o outfile
    sort numerically, reversed, on the third key, write into outfile.

    and in perl:
    my @args = qw/ sort -n -r -k 3 file -o outfile /; system( @args ) == 0 or die "something went wrong with: @args: $?\n";