my @q = qw(workstation_1_1 workstation_1_2 voiceserver_1_2 voiceserver_1_1); @q = map { join '_', @$_ } sort { $a->[1] <=> $b->[1] or $a->[2] <=> $b->[2] or $a->[0] cmp $b->[0] } map { [ split /_/ ] } @q; use Data::Dumper; print Dumper( \@q ); __OUTPUT__ 'voiceserver_1_1', 'workstation_1_1', 'voiceserver_1_2', 'workstation_1_2'