# sample data my %network = ( 10.1.0.1, { 'name' => 'vlan 2' } 10.2.0.2, { 'name' => 'vlan 3' } ); foreach my $network (sort { by_num($networks{$a}->{'name'}) <=> by_num($networks{$b}->{'name'}) or $a cmp $b } keys %networks ) { # do stuff... } # Extract the number from a string # Used to sort Network names by vlan number, rather than alphabetically sub by_num { my $key = shift; $key =~ /(\d+)/; return $1; } #### #### untested/concept code below # set the following to either 'alpha' or 'num' $sortby= 'alpha'; my %sort_network; $sort_network{'alpha'} = sub { $a->{'name'} cmp $b->{'name'} }; $sort_network{'num'} = sub { by_num($a->{'name'}) <=> by_num($b->{'name'} ) or $a->{'name'} cmp $b->{'name'}; foreach my $network (sort &$sort_network{$sortby} keys %networks ) { # do stuff... }