我无法在脑海中解决这个问题,对我来说太过分了,也许有人可以帮助我:
@Hosts = ("srv1","db1","srv2","db3","srv3","db3","srv3","db4","srv3","db5");
my $count = @Hosts;
$count= $count / 2;
my %hash;
$i = 0;
$ii = 1;
$j = 0;
$jj = 0;
while ($jj < $count) {
$hash{$j}{$Hosts[$i]} = $Hosts[$ii];
$i = $i + 2;
$ii = $ii +2;
$j++;
$jj++
}
print Dumper(\%hash);
输出:
$VAR1 = {
'4' => {
'srv4' => 'db3'
},
'1' => {
'srv2' => 'db3'
},
'3' => {
'srv3' => 'db3'
},
'0' => {
'srv1' => 'db1'
},
'2' => {
'srv3' => 'db3'
}
'5' => {
'srv3' => 'db5'
}
};
我知道这个丑陋的代码,我不知道如何做得更好,我需要做的是找到双服务器和双dbs,并将重复的位置和字符串放在一个类似的数组中,我想生成一个Nagvis地图文件。
Icinga Config文件包含如下所示的成员字符串:
members srv1, db1, srv2, db3, srv3, db3, srv3, db3, srv4
它有对服务器,db,server,db,这是Nagvis配置的一个示例:
define host {
object_id=5e78fb
host_name=srv1
x=237
y=122
}
define service {
object_id=30646e
host_name=srv1
service_description=db1
x=52
y=122
}
define host {
object_id=021861
host_name=srv2
x=237
y=217
}
define service {
object_id=a5e725
host_name=srv1
service_description=db2
x=52
y=217
}
提前致谢
答案 0 :(得分:2)
您需要准确说明您想要的内容。你的描述很难说清楚。
并且,您的代码状况非常糟糕。缩进循环和if语句如下:
while ($jj < $anzahl) {
$hash{$j}{$Hosts[$i]} = $Hosts[$ii];
$i = $i + 2;
$ii = $ii +2;
$j++;
$jj++
}
使您的代码更容易理解。您还使用通用名称。 @array
中存储了哪些数据?它是一个系统列表。称之为@systems
。 $i
和$jj
假设代表什么?你想要$hash{$j}{$Hosts[$i]}
代表什么?
您应 始终,始终 将以下行添加到您的计划顶部:
use strict;
use warnings;
如果您use strict
,则必须使用my
声明所有变量。这样可以确保您不会在一个地方执行@array
而在另一个地方执行@Hosts
。这两行将捕获大约90%的错误。
我不知道您是否需要连接到各种服务器的所有数据库系统的列表,或者您是否需要连接到数据库系统的各种服务器的列表。因此,我会给你们两个。
我猜你的@array
是一个列表中所有机器和数据库的列表:
use strict;
use warnings;
use feature qw(say); # Allows me to use "say" instead of "print"
use Data::Dumper;
my @systems = qw( # The qw(...) is like putting quotes around each word.
svr1 db1 # A nice way to define an array...
srv2 db3
srv3 db3
srv3 db4
srv3 db5
);
my %db_systems; # Database systems with their servers.
my %servers; # Servers with their database systems.
for (;;) { # Loop forever (until I say otherwise)
my $server = shift @systems;
#
# Let's check to make sure that there's a DB machine for this server
#
if ( not @systems ) {
die qq(Cannot get database for server "$server". Odd number of items in array);
}
my $database = shift @systems;
$servers{$server}->{$database} = 1;
$db_systems{$database}->{$server} = 1;
last if not @systems; # break out of loop if there are no more systems
}
say "Servers:" . Dumper \%servers;
say "Databases: " . Dumper \%db_systems;
这会产生:
Servers:$VAR1 = {
'srv3' => {
'db4' => 1,
'db3' => 1,
'db5' => 1
},
'svr1' => {
'db1' => 1
},
'srv2' => {
'db3' => 1
}
};
Databases: $VAR1 = {
'db4' => {
'srv3' => 1
},
'db3' => {
'srv3' => 1,
'srv2' => 1
},
'db5' => {
'srv3' => 1
},
'db1' => {
'svr1' => 1
}
};
这接近你想要的吗?
嗨,这是有效的!!现在我需要了解如何访问值以在我的文件中打印它们。这个散列哈希的东西对我来说是个不错的选择。谢谢你的快速帮助!
您需要阅读References上的Perl教程和参考文献中的Perl Reference Page。
在Perl中,所有数据都是标量,这意味着变量会讨论单个值。在其他编程语言中,您有结构或记录,但不是Perl。
即使数组和散列也只是各个数据位的集合。当你需要更复杂的东西时会发生什么?
引用是另一个Perl数据结构的内存位置。您可以引用标量变量,例如$foo
,但在大多数情况下,这对您没有好处。这有用的地方是你有一个指向数组或哈希的引用。这样,您可以使用更复杂的结构来表示此数据。
想象一下包含十个项目的数组($foo[0]
到$foo[9]
)。数组中的每个条目都指向另一个包含十个项目的数组。现在这里引用了101个单独的数组。我们可以将它们视为单一结构,但记住它们是独立的数组非常重要。
我在$foo[0]
处引用了一个数组。如何访问阵列本身?我执行所谓的取消引用。为此,我在前面使用右侧 sigil 的花括号。 (sigil是您在Perl变量前面看到的$
,@
或%
:
$foo[0]; # Reference to an array
my @temp = @{ $foo[0] }; # Dereferencing.
my $temp[0]; # Now I can access that inner array
每次我必须取消引用它时必须使用一个临时数组是相当笨拙的,所以我不必:
$foo[0]; # Reference to an array
my $value = ${ $foo[0] }[0]; # Getting the value of an item in my array reference
你可以看到最后有点难读。想象一下,如果我有一个项目数组的哈希哈希:
my $phone = ${ ${ ${ $employee{$emp_number} }{phone} }[0] }{NUMBER};
有点笨拙。幸运的是,Perl允许您使用一些快捷方式。首先,我可以嵌套引用并使用默认优先级:
my $phone = $employee{$emp_number}{phone}[0]{NUMBER};
我更喜欢使用->
表示法:
my $phone = $employee{$emp_number}->{phone}->[0]->{NUMBER};
箭头概念更清晰,因为它将各个部分分开,它会提醒你这些是引用!。并且,不是一些复杂的结构数据结构。这有助于提醒您何时必须取消引用,例如当您使用key
,pop
或push
命令时:
for my $field ( keys %{ $employee } ) { # Dereference the hash
say "Field $field = " . $employee{$emp_number}->{$field}
if ( not ref $employee{$emp_number}->{$field} );
}
查看ref以查看它的作用以及为什么我只对ref
返回空字符串时打印字段感兴趣。
到现在为止,您应该能够看到如何使用->
语法访问哈希哈希:
my $db_for_server = $servers{$server}->{$database};
你可以使用两个循环:
for my $server ( keys %servers } {
my %db_systems = %{ $servers{$server} }; # Dereferencing
for my $db_system ( keys %db_systems } {
say "Server $server has a connection to $db_systems{$db_system}";
}
}
或者,没有中间哈希......
for my $server { keys %servers } {
for my $db_system ( keys %{ $servers{$server} } ) {
say "Server $server has a connection to " . $servers{$server}->{$db_system};
}
}
现在,请到Modern Perl获取 好 一书。您需要学习良好的编程技术,例如使用好的变量名,缩进,并使用 strict 和警告,以帮助您编写更易于破译和支持的更好的程序。