my %cols_idx = do { my $i = 0; map { $_ => $i++ } @cols }; #### my @data = map [ split " " ] => ; #### #!/usr/local/bin/perl use strict; use warnings; use Data::Dumper; my @cols = qw ( lastname firstname cno unit ward dateadmission datebirth ); my %cols_idx = do { my $i = 0; map { $_ => $i++ } @cols }; my %parameters = ( lastname => [ qw( U a ) ], firstname => [ qw( U a ) ], cno => [ qw( U n ) ], unit => [ qw( U s ) ], ward => [ qw( U n ) ], dateadmission => [ qw( D a ) ], datebirth => [ qw( D a ) ], ); my @data = map [ split ] => ; print Dumper sort_by_column( \@data, @ARGV ? @ARGV : qw{ lastname firstname cno } ); ########## SUBROUTINES ########## sub make_single_comparator { print "parms: @_\n"; my $data = shift; my $col = shift; my $asc = shift; my $type = shift; my $idx = $cols_idx{$col}; print "idx: $idx\n"; my %subs = ( U => { a => sub { lc($a->[$idx]) cmp lc($b->[$idx]) }, n => sub { $a->[$idx] <=> $b->[$idx] }, s => sub { $a->[$idx] cmp $b->[$idx] }, }, D => { a => sub { lc($b->[$idx]) cmp lc($a->[$idx]) }, n => sub { $b->[$idx] <=> $a->[$idx] }, s => sub { $b->[$idx] cmp $a->[$idx] }, }, ); $subs{$asc}{$type}; } sub sort_maker { my @littlesubs = @_; sub { foreach my $sub (@littlesubs) { my $result = $sub->(); return $result if $result; } }; } sub sort_by_column { my $data = shift; my @order = @_; my $sortref = sort_maker( map { make_single_comparator( $data, $_, @{$parameters{$_}}) } @order ); my @results = sort $sortref @$data; return [ @results ]; } __DATA__ HERNANDEZ HECTOR 456791 SAMSON 0217 2001-07-25 1963-08-01 VASQUEZ JOAQUIN 456789 SAMSON 0209 1990-11-14 1970-03-25 JONES TIMOTHY 803092 LAVER 0103 2001-03-19 1969-06-29 SMITH BETTY_SUE 698389 SAMSON 0211 1992-01-23 1949-08-12 VASQUEZ LEONARDO 456788 LAVER 0107 1990-08-23 1970-15-23 SMITH HAROLD 359962 TRE 0111 2001-07-19 1973-10-02 VASQUEZ ADALBERTO 786792 LAVER 0104 2001-07-26 1973-08-17 VASQUEZ JORGE 456787 LAVER 0105 1986-01-17 1956-01-13 VAZQUEZ TOMASINA 456790 LAVER 0110 1980-11-14 1960-14-02 WILSON SYLVESTER 498703 LAVER 0110 1983-04-02 1953-06-22 VASQUEZ ALBERTO 906786 TRE 0111 2001-07-15 1953-02-28