$ perl -Mstrict -Mwarnings -E ' use constant { FIRST => 0, SECOND => 1, THIRD => 2 }; my @data = qw{ A:C:1 A:C:2 A:D:1 A:D:2 B:C:1 B:C:2 B:D:1 B:D:2 }; say "Raw data:"; say for @data; say "Sorted data:"; say join ":" => @$_ for sort { $b->[FIRST] cmp $a->[FIRST] || $a->[SECOND] cmp $b->[SECOND] || $b->[THIRD] <=> $a->[THIRD] } map { [ split /:/ ] } @data; ' Raw data: A:C:1 A:C:2 A:D:1 A:D:2 B:C:1 B:C:2 B:D:1 B:D:2 Sorted data: B:C:2 B:C:1 B:D:2 B:D:1 A:C:2 A:C:1 A:D:2 A:D:1 #### $a->[LAST_NAME] cmp $b->[LAST_NAME] || $a->[FIRST_NAME] cmp $b->[FIRST_NAME]