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

good day to all monks .. and may your tribe increase :)

I am a newbie to perl and need info on a sorting problem. I have a file that has 3 columns .. the first and second being numeric and the third being aplha-numeric. eg.
1,2,this
2,3,that
2,3,this
1,4,all
and so on ..

Now, I was successful in sorting the above file either in numeric .. based on the first column or alpha-numeric based on the third column.
What I need now is to sort the whole file first on the third column and within that sort them on the firt column .. (Hope I am making sense .. ) take the above eg. the o/p reqd. is
1,4,all
2,3,that
1,2,this
2,3,this
and so on ..

I guess I am doing something wrong. Thus I came to the monastery gates for salvation ... Thanks in advance

Replies are listed 'Best First'.
Re (tilly) 1: Multiple Sort on a file
by tilly (Archbishop) on Aug 14, 2001 at 15:35 UTC
    There is also a more compact way to do this called the Schwartzian Transform. In this case that comes out to the script:
    #! /usr/bin/perl print map {join ",", @$_} sort {$a->[2] cmp $b->[2] or $a->[0] <=> $b->[0]} map {[split /,/, $_, 3]} <>;
    which should be read after reading about map, and should be read bottom up. You would call it like this:
    perl scriptname < input_file > output_file
Re: Multiple Sort on a file
by Masem (Monsignor) on Aug 14, 2001 at 15:25 UTC
    You'll want to read the entire file into an array of arrays, and then use perl's nice sort function to sort that array, finally writing the data back to the file. Sample code is below:
    my @data while (my $line = <FILE>) { my @elements = split /,/, $line; push @data, \@elements; # need to store as ref } @data = sort { $$a[2] cmp $$b[2] or $$a[0] <=> $$b[0] } @data; # cmp and <=> are string and numerical comparison operators, # respectively; if the left hand arg is less than the right, # they return -1, if equal, 0, and otherwise 1, so if the # 3rd column of the array is the same, we get a 0, which # triggers the 'or' and the second comparison open OUTFILE, ">$outfile" or die $!; foreach my $item (@data) { print OUTFILE join ',', @$item; print OUTFILE "\n"; }

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain

      Thanks monks !!!
      I have been enlightened !!
      I was trying the cmp and <=> separately. I didn't think you could combine them .. The explanation for the 'or' was a great help .. Thanks again ..
      Someday, I hope to be answering queries here .. Bless me so I get there .. ;-)
Re: Multiple Sort on a file
by Hofmator (Curate) on Aug 14, 2001 at 15:35 UTC