# When sorting lists of files, I want the index file to always come first. if ($c =~ /^index\./) { return -1; } elsif ($d =~ /^index\./) { return 1; } #### $ perl PM1021473_3_unstable.pl index.0001 afile article -1 index.0001 index.0005 article -1 index.9999 index.0005 article -1 #### #!/usr/bin/perl # # PM1021473_3_unstable.pl # use strict; use warnings; use HTML::Entities; while () { s/\s+$//; my @args = split /\s+/,$_; push @args, my_sort(@args); printf "%-10s %-10s %-10s %d\n", @args; } ... your sort routine ... __DATA__ index.0001 afile article index.0001 index.0005 article index.9999 index.0005 article #### sub my_sort_article { my ($c,$d,$type) = @_; $c = lc($c); $d = lc($d); my $t = my_sort_index($c, $d); return $t if $t; # Written with the help of kent/n in #perl on freenode. for ($c, $d) { s/<.+?>//g; # Strip out any html tags. s/\s*\b(A|a|An|an|The|the)(_|\s)//xi; # Strip off leading articles (in English). decode_entities($_); } if ( $c =~/^((\d|,|\.)+)(.*)$/ && $d =~ /^((\d|,|\.)+)(.*)$/) { # Get the leading number. (my $e = $c) =~ s/^((\d|,|\.)+)(.*)$/$1/; (my $f = $d) =~ s/^((\d|,|\.)+)(.*)$/$1/; # Take any commas out of the number. s/,//g for ($e,$f); # Get the remaining parts of the string. (my $g = $c) =~ s/^((\d|,|\.)+)(.*)$/$3/; (my $h = $d) =~ s/^((\d|,|\.)+)(.*)$/$3/; # First compare the numbers, then compare the remaining parts of the string. $e <=> $f || $g cmp $h } else { $c cmp $d; } } sub my_sort_name { # When I sort by name I prefer lastname firstname. # I have not yet written this to account for Sr., Jr., or Roman numerals after the last name. my ($c,$d,$type) = @_; $c = lc($c); $d = lc($d); # ?Did you really want this check for name sorting? my $t = my_sort_index($c, $d); return $t if $t; for ($c,$d) { s/\|.+$//; $_ = join(' ', (reverse split(/(?:_|\s)(?=[^_\s]+$)/, $_,2))) if $_ !~ /^_/; s/^_//; s/^(A|a|An|an|The|the)(_|\s)//; } return $c cmp $d; } #### sub split_out_leading_number { my $s = shift; if ( $s =~/^((\d|,|\.)+)(.*)$/) { my ($leading_number, $rest) = ($1,$3); # Take any commas out of the number. $leading_number =~ s/,//g; return ($leading_number, $rest); } die "split_out_leading_number received bogus input '$s'!\n"; } #### sub my_sort_article { my ($c,$d,$type) = @_; $c = lc($c); $d = lc($d); my $t = my_sort_index($c, $d); return $t if $t; # Written with the help of kent/n in #perl on freenode. for ($c, $d) { s/<.+?>//g; # Strip out any html tags. s/\s*\b(A|a|An|an|The|the)(_|\s)//xi; # Strip off leading articles (in English). decode_entities($_); } if ( $c =~/^((\d|,|\.)+)(.*)$/ && $d =~ /^((\d|,|\.)+)(.*)$/) { my ($num1, $text1) = split_out_leading_number($c); my ($num2, $text2) = split_out_leading_number($d); # First compare the numbers, then compare the remaining parts of the string. $num1 <=> $num2 || $text1 cmp $text2 } else { $c cmp $d; } } #### my @list = ( qw( apple Alpha aLBAtross aLbAcOre etc... ) ); my @result = sort {uc($a) cmp uc($b)} @original; #### my @list = ( [qw( APPLE apple )], [qw( ALPHA alpha )], [qw( ALBATROSS aLBAtross )], [qw( ALBACORE aLbAcOrE)], etc... ); #### my @result = sort { $a->[0] cmp $b->[0] } @list; #### my @list = ( [qw( ALBACORE aLbAcOrE)], [qw( ALBATROSS aLBAtross )], [qw( ALPHA alpha )], [qw( APPLE apple )], etc... ); #### my @list = ( qw( apple Alpha aLBAtross aLbAcOre etc... ) ); # Convert our list into the ( [APPLE apple], ... ) form with map: @result = map { [ uc($_), $_ ] } @list; # Now sort the list: @result = sort {$a->[0] cmp $b->[0]} @result; # Now convert the resulting list back into (aLbAcOrE aLBAtross...) format: @result = map { $_->[1] } @result; #### my @list = ( qw( apple Alpha aLBAtross aLbAcOre etc... ) ); my @result = map {$_->[1] } # .sgnirts desacreppu eht lla tou pirts # sort {$a->[0] cmp $b->[0]} # neht dna ,sgnirts desacreppu eht no tros # map { [ uc($_), $_ ] } # ,gnirts eht fo noisrev desacreppu eht dda # @list; # ,tsil a neviG #