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

Hi, I have to sort a file depending on a particular value, the problem is that the value can be number,string or alphanumeric. So which comparison opertor will work on all these? This is the script :
use strict; my $column=3; my @F; my @sort_col; my @lines; my $file=$ARGV[0]; while(<>) { #print "Input line " .$_; @F=split(/\|/,$_); print "Array elesems $F[3]\n"; push @sort_col, $F[$column]; push @lines, "$_"; } print @lines[sort{ $sort_col[$a] lt $sort_col[$b] } 0..$#sort_col] ;
And the input file :
D|0|95465tan|2|4|4|14028.77|0.00|BF2-002|22/09/2009|07/01/2009|06/09/2 +009|45544564| D|0|954564545|1|4|abar_BF4|4|3913.17|0.00|accabar_BF4-003|22/09/2009|0 +7/02/2009|06/09/2009|10254754| D|0|a454654|1|4|ar_BF4|4|3913.17|0.00|acctrabar_BF4-003|22/09/2009|07/ +02/2009|06/09/2009|11122323| D|0|Chking|1|4|arabar_BF4|4|3913.17|0.00|acarabar_BF4-003|22/09/2009|0 +7/02/2009|06/09/2009|11122323|
Thanks

Replies are listed 'Best First'.
Re: Comparison of alphanumeric strings
by almut (Canon) on Sep 17, 2009 at 10:34 UTC
    the problem is that the value can be number,string or alphanumeric

    Maybe you want Sort::Naturally?   (I figure you're not satisfied with the results you'd get from string sort...)

Re: Comparison of alphanumeric strings
by GrandFather (Saint) on Sep 17, 2009 at 10:40 UTC

    How do you want them ordered?

    The string lt operator simply isn't going to work. sort expects an expression that returns one of three values: less than 0 iff lhs less than rhs, 0 iff lhs equals rhs, and greater than 0 iff lhs greater than rhs. The cmp operator performs that operation for strings and <=> (the spaceship operator) does it for numerical values.

    If you want some other comparison you need to roll up your own expression that generates -1, 0 or 1 as appropriate for combinations of lhs and rhs values, but you need to specify the desired sort order before you can code it!


    True laziness is hard work
      I want to order them in ascending order depending on the numbers first, then strings and then alphanumeric

        In that case you really need two sort criteria - type of string and actual string. Consider:

        use warnings; use strict; my $column=2; my @sort_col; my @lines; while(<DATA>) { my @F=split(/\|/,$_); push @sort_col, $F[$column]; push @lines, "$_"; } @sort_col = map {[$_ => /^\d+$/ ? 0 : /^\D+$/ ? 1 : 2]} @sort_col; my @sortedOrder = sort {$sort_col[$a][1] cmp $sort_col[$b][1] or $sort_col[$a][0] cm +p $sort_col[$b][0]} 0 .. $#sort_col; print @lines[@sortedOrder]; __DATA__ D|0|95465tan|2|4|4|14028.77|0.00|BF2-002|22/09/2009|07/01/2009|06/09/2 +009|45544564| D|0|954564545|1|4|abar_BF4|4|3913.17|0.00|accabar_BF4-003|22/09/2009|0 +7/02/2009|06/09/2009|10254754| D|0|a454654|1|4|ar_BF4|4|3913.17|0.00|acctrabar_BF4-003|22/09/2009|07/ +02/2009|06/09/2009|11122323| D|0|Chking|1|4|arabar_BF4|4|3913.17|0.00|acarabar_BF4-003|22/09/2009|0 +7/02/2009|06/09/2009|11122323|

        Prints:

        D|0|954564545|1|4|abar_BF4|4|3913.17|0.00|accabar_BF4-003|22/09/2009|0 +7/02/2009|06/09/2009|10254754| D|0|Chking|1|4|arabar_BF4|4|3913.17|0.00|acarabar_BF4-003|22/09/2009|0 +7/02/2009|06/09/2009|11122323| D|0|95465tan|2|4|4|14028.77|0.00|BF2-002|22/09/2009|07/01/2009|06/09/2 +009|45544564| D|0|a454654|1|4|ar_BF4|4|3913.17|0.00|acctrabar_BF4-003|22/09/2009|07/ +02/2009|06/09/2009|11122323|

        True laziness is hard work