迭代多级哈希
Iterating over Multi-Level Hashes
我正在将 CSV 文件读入多级哈希。我正在尝试遍历哈希。
这是加载哈希的代码。有用。如果我使用 Dumper 打印它,我得到了我期望的结果。
use Data::Dumper;
my $connectionsinfile = "switchconnections.csv";
my %switchportinfo;
open (my $INFILE,'<',$connectionsinfile) or die "Couldn't open SVC input file $connectionsinfile\n$!";
my @recs = <$INFILE>;
close $INFILE;
chomp @recs;
use constant { true => 1, false => 0};
my @header = split',', $recs[0];
# now that we have the header, remove it from the array
shift @recs;
foreach my $rec (@recs) {
my @data = split(',',$rec);
@row_data{@header} = @data;
my $switchname = $row_data{'Switch Name'};
my $switchport = $row_data{'Port'};
$switchportinfo{$switchname}{$switchport} = {%row_data};
}
此代码有效,除了它打印外键和内键,然后打印内键的值 'HASH(XXXXXX)'
for $key (keys %switchportinfo)
{
print "$key: \n";
for $ele (keys %{$switchportinfo{$key}})
{
print " $ele: " . $switchportinfo{$key}->{$ele} . "\n";
}
}
此代码导致错误“键的 arg 1 类型必须是散列或数组(不是 key/value 散列片)在 test2.pl”}
我希望能够打印内部哈希值。
for $key (keys %switchportinfo)
{
print "$key: \n";
for $ele (keys %{$switchportinfo{$key}})
{
print "$ele: \n";
for $ele2 (keys %{switchportinfo{$key}{$ele}}) {
print " $ele2: " . $switchportinfo{$key}{$ele}->{$ele2}. "\n";
}
}
}
您在 %{switchportinfo{$key}{$ele}}
中缺少一个 $
。始终使用 use strict; use warnings;
.
最后一个片段在其他方面是正确的。但是让我们使用更好的名称,例如第一个片段中使用的名称。
for my $switchname (keys %switchportinfo)
{
print "switchname: $switchname\n";
for my $switchport (keys %{ $switchportinfo{$switchname} })
{
print " switchport: $switchport\n";
for my $header (keys %{ $switchportinfo{$switchname}{$switchport} }) {
print " $header: $switchportinfo{$switchname}{$switchport}{$header}\n";
}
}
}
以下示例代码演示了处理输入数据和输出收集记录的一种可能情况。
注意:未提供输入文件格式,示例代码基于可能输入格式的假设
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $debug = 0;
my($header,@header,@recs,%sw_info);
$header = <DATA>;
@recs = <DATA>;
@header = split(',',$header);
chomp @header;
chomp @recs;
foreach my $rec (@recs) {
my %sw;
@sw{@header} = split(',',$rec);
$sw_info{$sw{name}}{$sw{port}} = \%sw;
}
say Dumper(\%sw_info) if $debug;
for my $sw ( sort keys %sw_info ) {
say 'Switch: ' . $sw;
say "=" x 45;
for my $port ( keys %{$sw_info{$sw}} )
{
my $port_info = $sw_info{$sw}{$port};
say "\t$_ => $port_info->{$_} " for sort keys %$port_info;
say "\t" . '-' x 25;
}
}
__DATA__
r #,name,port,ip,location
1,sw1,12,192.168.0.1,office 35/north side
2,sw4,8,192.168.1.15,office 31/west side
3,sw1,24,192.168.0.13,office 41/south side
4,sw1,15,192.168.0.11,office 23/south side
输出
Switch: sw1
=============================================
ip => 192.168.0.11
location => office 23/south side
name => sw1
port => 15
r # => 4
-------------------------
ip => 192.168.0.13
location => office 41/south side
name => sw1
port => 24
r # => 3
-------------------------
ip => 192.168.0.1
location => office 35/north side
name => sw1
port => 12
r # => 1
-------------------------
Switch: sw4
=============================================
ip => 192.168.1.15
location => office 31/west side
name => sw4
port => 8
r # => 2
-------------------------
我正在将 CSV 文件读入多级哈希。我正在尝试遍历哈希。
这是加载哈希的代码。有用。如果我使用 Dumper 打印它,我得到了我期望的结果。
use Data::Dumper;
my $connectionsinfile = "switchconnections.csv";
my %switchportinfo;
open (my $INFILE,'<',$connectionsinfile) or die "Couldn't open SVC input file $connectionsinfile\n$!";
my @recs = <$INFILE>;
close $INFILE;
chomp @recs;
use constant { true => 1, false => 0};
my @header = split',', $recs[0];
# now that we have the header, remove it from the array
shift @recs;
foreach my $rec (@recs) {
my @data = split(',',$rec);
@row_data{@header} = @data;
my $switchname = $row_data{'Switch Name'};
my $switchport = $row_data{'Port'};
$switchportinfo{$switchname}{$switchport} = {%row_data};
}
此代码有效,除了它打印外键和内键,然后打印内键的值 'HASH(XXXXXX)'
for $key (keys %switchportinfo)
{
print "$key: \n";
for $ele (keys %{$switchportinfo{$key}})
{
print " $ele: " . $switchportinfo{$key}->{$ele} . "\n";
}
}
此代码导致错误“键的 arg 1 类型必须是散列或数组(不是 key/value 散列片)在 test2.pl”}
我希望能够打印内部哈希值。
for $key (keys %switchportinfo)
{
print "$key: \n";
for $ele (keys %{$switchportinfo{$key}})
{
print "$ele: \n";
for $ele2 (keys %{switchportinfo{$key}{$ele}}) {
print " $ele2: " . $switchportinfo{$key}{$ele}->{$ele2}. "\n";
}
}
}
您在 %{switchportinfo{$key}{$ele}}
中缺少一个 $
。始终使用 use strict; use warnings;
.
最后一个片段在其他方面是正确的。但是让我们使用更好的名称,例如第一个片段中使用的名称。
for my $switchname (keys %switchportinfo)
{
print "switchname: $switchname\n";
for my $switchport (keys %{ $switchportinfo{$switchname} })
{
print " switchport: $switchport\n";
for my $header (keys %{ $switchportinfo{$switchname}{$switchport} }) {
print " $header: $switchportinfo{$switchname}{$switchport}{$header}\n";
}
}
}
以下示例代码演示了处理输入数据和输出收集记录的一种可能情况。
注意:未提供输入文件格式,示例代码基于可能输入格式的假设
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $debug = 0;
my($header,@header,@recs,%sw_info);
$header = <DATA>;
@recs = <DATA>;
@header = split(',',$header);
chomp @header;
chomp @recs;
foreach my $rec (@recs) {
my %sw;
@sw{@header} = split(',',$rec);
$sw_info{$sw{name}}{$sw{port}} = \%sw;
}
say Dumper(\%sw_info) if $debug;
for my $sw ( sort keys %sw_info ) {
say 'Switch: ' . $sw;
say "=" x 45;
for my $port ( keys %{$sw_info{$sw}} )
{
my $port_info = $sw_info{$sw}{$port};
say "\t$_ => $port_info->{$_} " for sort keys %$port_info;
say "\t" . '-' x 25;
}
}
__DATA__
r #,name,port,ip,location
1,sw1,12,192.168.0.1,office 35/north side
2,sw4,8,192.168.1.15,office 31/west side
3,sw1,24,192.168.0.13,office 41/south side
4,sw1,15,192.168.0.11,office 23/south side
输出
Switch: sw1
=============================================
ip => 192.168.0.11
location => office 23/south side
name => sw1
port => 15
r # => 4
-------------------------
ip => 192.168.0.13
location => office 41/south side
name => sw1
port => 24
r # => 3
-------------------------
ip => 192.168.0.1
location => office 35/north side
name => sw1
port => 12
r # => 1
-------------------------
Switch: sw4
=============================================
ip => 192.168.1.15
location => office 31/west side
name => sw4
port => 8
r # => 2
-------------------------