我正在尝试按HoA中的值排序,其中key => [a,b,c]我想按字母顺序排序,并且尝试阅读并没有成功。我认为是逗号,但请帮忙!以下是一个简短的摘要。原始数据与数据转储相对于CLI的显示方式完全相同。我必须使用某种定界符,否则cli输出是乏味的!谢谢!
use strict;
use warnings;
my ( $lsvm_a,$lsvm_b,%hashA,%hashB );
my $vscincludes = qr/(^0x\w+)\,\w+\,\w+.*/; #/
open (LSMAP_A, "-|", "/usr/ios/cli/ioscli lsmap -vadapter vhost7 -field clientid vtd backing -fmt ," ) or die $!;
while ($lsvm_a = (<LSMAP_A>)) {
chomp($lsvm_a);
next unless $lsvm_a =~ /$vscincludes/;
@{$hashA{$1}} = (split ',', $lsvm_a);
}
open (LSMAP_B, "-|", "/usr/sbin/clcmd -m xxxxxx /usr/ios/cli/ioscli lsmap -vadapter vhost29 -field clientid vtd backing -fmt ," ) or die $!;
while ($lsvm_b = (<LSMAP_B>)) {
chomp($lsvm_b);
next unless $lsvm_b =~ /$vscincludes/;
push @{$hashA{$1}}, (split ',', $lsvm_b);
}
print "\n\nA:";
for my $key ( sort { $hashA{$a} cmp $hashA{$b} } keys %hashA ) {
print "$key => '", join(", ", @{$hashA{$key}}), "'\n";
}
##
print "===\nB:";
foreach my $key ( sort { (@{$hashB{$a}}) cmp (@{$hashB{$b}}) } keys %hashB ) {
print "$key ==> @{$hashB{$key}}\n";
}
print "\n\n__DATA_DUMPER__\n\n";
use Data::Dumper; print Dumper \%hashA; print Dumper \%hashB;
输出
A:0x00000008 =>'0x00000008,atgdb003f_avg01,hdisk10,atgdb003f_ovg01,hdisk96,atgdb003f_pvg01,hdisk68,atgdb003f_rvg01,hdisk8,vtscsi0,atgdb003f_data.5bcd027df10f7bc9a924===B:0x00000008 =>'0x00000008,atgdb003f_avg01,hdisk10,atgdb003f_data,atgdb003f_data.5bcd027df10f27bf9a880ce7bc1dd924,atgdb003f_ovg01,hdisk96,atgdb003f_pvg01,hdisk_68,atgdb003__DATA_DUMPER__$ VAR1 = {'0x00000008'=> ['0x00000008','atgdb003f_avg01','hdisk10','atgdb003f_ovg01','hdisk96','atgdb003f_pvg01','hdisk68','atgdb003f_rvg01','hdisk8','vtscsi0','atgdb003f_data.5bcd027df10f27bf9a880ce7bc1dd924']};$ VAR1 = {'0x00000008'=> ['0x00000008','atgdb003f_avg01','hdisk10','atgdb003f_data','atgdb003f_data.5bcd027df10f27bf9a880ce7bc1dd924','atgdb003f_ovg01','hdisk96','atgdb003f_pvg01','hdisk68','atgdb003f_rvg01','hdisk8']};### CLI输出###### 0x00000008,atgdb003f_avg01,hdisk10,atgdb003f_ovg01,hdisk96,atgdb003f_pvg01,hdisk68,atgdb003f_rvg01,hdisk8,vtscsi0,atgdb003f_data.5bcd027df10f27bf9a880ce7b### 0x00000008,atgdb003f_avg01,hdisk10,atgdb003f_data,atgdb003f_data.5bcd027df10f27bf9a880ce7bc1dd924,atgdb003f_ovg01,hdisk96,atgdb003f_pvg01,hdisk68,atgdb003f_rv
Update毕竟,arrayrefs(哈希值)具有多个元素,需要进行排序。然后
for my $key (keys %h) { @{$h{$key}} = sort @{$h{$key}} }
或更有效地†(并且为statement modifier形式,具有较少的噪音但可能不太清晰)
$h{$_} = [ sort @{$h{$_}} ] for keys %h;
[sort默认情况下根据需要使用字典顺序排序。
键希望按数字进行排序,但是请注意,尽管我们可以重写数组以使它们进行排序,但是对于哈希来说并不是这样,哈希本质上是无序的。我们当然可以打印排序
foreach my $k (sort { $a <=> $b } keys %h) { ... }
如果键不是数字,则会发出警告。
† 在v5.16和v5.30.0的三台不同机器上,按我的基准分别为56%– 60%
原始帖子
我认为您需要对一个具有arrayref作为值的哈希进行排序,从而该arrayref具有单个元素。然后排序,首先,元素
foreach my $key ( sort { $hashB{$a}->[0] cmp $hashB{$b}->[0] } keys %hashB ) {
print "$key ==> @{$hashB{$key}}\n";
}
请参见cmp
下的Equality operators in perlop运算符。它需要标量,并按字符串进行比较(因此,尝试从问题中对数组进行排序是错误的,因为cmp
将获得要排序的那些数组的长度!)
据我了解,您要排序的哈希像
$VAR1 = {
'0x00000008' => [ 'atgdb003f_avg01,hdisk10,atgdb003f_ovg01,...' ],
...
}
其中每个值是一个只有一个元素的arrayref。