You can break the values into parts so that you can sort each section appropriately, whether by alpha or by numerical comparisons:
my @keys = qw(
FastEthernet1
GigabitEthernet1/1
GigabitEthernet1/10
GigabitEthernet1/2
GigabitEthernet1/20
);
my @sorted = sort {
my ($a_name, $a_num1, $a_num2) = $a =~ m{(.*?)(\d+)(?:/(\d+))?};
my ($b_name, $b_num1, $b_num2) = $b =~ m{(.*?)(\d+)(?:/(\d+))?};
$a_name cmp $b_name or $a_num1 <=> $b_num1 or $a_num2 <=> $b_num2;
} @keys;
print "$_\n" for @sorted;
Or using some more advanced regex techniques:
my @sorted = sort {
local ( $a, $b ) = map { m{(?<name>\D+) (?<num1>\d+) (?: / (?<num2>\d+))?}x ? {%+} : die "Can't parse: $_" } ( $a, $b );
$a->{name} cmp $b->{name} or $a->{num1} <=> $b->{num1} or $a->{num2} <=> $b->{num2}
} @keys;
Or use the module Sort::Key::Natural
, to automatically sort numerical parts numerically:
use Sort::Key::Natural qw(natsort);
my @sorted = natsort @keys;
print "$_\n" for @sorted;
Both methods output:
FastEthernet1
GigabitEthernet1/1
GigabitEthernet1/2
GigabitEthernet1/10
GigabitEthernet1/20