Perl INI文件使用数组或哈希
我必须将PHP脚本转换为Perl 在我的PHP脚本中,我解析了一个包含数组元素的ini文件,例如Perl INI文件使用数组或哈希,perl,file,hash,ini,Perl,File,Hash,Ini,我必须将PHP脚本转换为Perl 在我的PHP脚本中,我解析了一个包含数组元素的ini文件,例如 [RADIUS] SRV[] = "server 1" SRV[] = "server 2" SRV[] = "server 3" ... SRV[] = "server n" 这在PHP中工作得很好,我的问题是,我可以在Perl中使用相同的ini文件,还是必须按照以下方式重写它 [RADIUS] SRV1 = "server 1" SRV2 = "server 2" SRV3 = "server
[RADIUS]
SRV[] = "server 1"
SRV[] = "server 2"
SRV[] = "server 3"
...
SRV[] = "server n"
这在PHP中工作得很好,我的问题是,我可以在Perl中使用相同的ini文件,还是必须按照以下方式重写它
[RADIUS]
SRV1 = "server 1"
SRV2 = "server 2"
SRV3 = "server 3"
...
SRV4 = "server n"
这在CPAN中并不清楚
对于第一个变量,我可以遍历散列并通过while循环读取我的值,这样我就不必担心是否删除了编号一致的项
欢迎任何提示!提前谢谢。如果您熟悉一点正则表达式,也可以逐行读取文件并存储所需的值。我在下面的例子中使用了这个 如果您不需要“服务器1”、“服务器2”的特定顺序。。值,则可以使用哈希,否则,使用数组 这里,根据您的示例,提供了一个示例测试文件:
%_Host@User> cat srv.txt
SRV[] = "server 1"
SRV[] = "server 2"
SRV[] = "server 3"
SRV[] = "server 109"
SRV[] = "server 51"
%_Host@User>
我通过将文件转换为脚本来读取它,然后生成一个散列和一个数组,如下面的Data::Dumper输出所示
%_Host@User> cat srv.txt |perl test.pl
# Hash output [unordered]
$VAR1 = '"server 109"';
$VAR2 = 1;
$VAR3 = '"server 51"';
$VAR4 = 1;
$VAR5 = '"server 1"';
$VAR6 = 1;
$VAR7 = '"server 3"';
$VAR8 = 1;
$VAR9 = '"server 2"';
$VAR10 = 1;
# Array output [in order]
$VAR1 = '"server 1"';
$VAR2 = '"server 2"';
$VAR3 = '"server 3"';
$VAR4 = '"server 109"';
$VAR5 = '"server 51"';
%_Host@User>
现在你有了两种选择,你可以随心所欲了
下面是脚本:它的逻辑是:如果行与“server”匹配,则处理并提取值并存储在哈希和数组中,否则跳过
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper ;
my %hash ;
my @array ;
while (<>)
{
if (m/server/) {
if (m/^.+? = (.+)$/) {
$hash{$1} = 1 ;
push (@array, $1) ;
}
}
}
print Dumper %hash ;
print Dumper @array ;
#/usr/bin/perl
严格使用;
使用警告;
使用数据::转储程序;
我的%hash;
我的@数组;
而()
{
如果(m/server/){
如果(m/^.+?=(.+)$/){
$hash{$1}=1;
推送(@array,$1);
}
}
}
打印转储程序%hash;
打印转储程序@数组;
您可以直接使用ini文件,但需要做一些调整
根据报告:
val($section,$parameter[,$default])
返回节中指定参数($parameter)的值
$section,如果没有节或没有,则返回undef(如果指定,则返回$default)
给定节的参数存在
如果希望多行/值字段作为数组返回,只需
指定一个阵列作为接收器:
@values = $cfg->val('Section', 'Parameter');
多行/值
在标量上下文中返回的字段将使用$/
(输入记录分隔符,默认值为\n)如果已定义,则
将使用\n连接值
以下是:
use 5.014;
use warnings;
use Config::IniFiles;
use Data::Dumper;
my $cfg = Config::IniFiles->new( -file => "./conf.ini" );
my @v = $cfg->val( 'RADIUS', 'SRV[]' );
say Dumper \@v;
生成一个4元素数组
$VAR1 = [
'"server 1"',
'"server 2"',
'"server 3"',
'"server n"'
];
另请注意:
- 参数名称使用
SRV[]
- 返回的数组元素包含
引号字符“
use Config::IniFiles;
# Read Ini File
my %MyCfg;
tie %MyCfg, 'Config::IniFiles', ( -file => "..".$MyPathSep."ini".$MyPathSep."file.ini" );
foreach my $List1 (sort keys %{$MyCfg{'DataCenters'}}) {
if (ref $MyCfg{'DataCenters'}{$List1} eq 'ARRAY') {
foreach my $List2 (sort keys @{$MyCfg{'DataCenters'}{$List1}}) {
print $MyCfg{'DataCenters'}{$List1}[$List2]."\n";
}
} else {
print $MyCfg{'DataCenters'}{$List1}."\n";
}
}
对于输入部分:
[DataCenters]
; DC in location a
LOCa[] = "DC1"
LOCa[] = "DC2"
LOCa[] = "DC3"
LOCa[] = "DC4"
; DC in location b
LOCb[] = "DC5"
输出为:
scripts\bin>perl switchcfg.pl
"DC1"
"DC2"
"DC3"
"DC4"
"DC5"
谢谢你的贡献!
当做
Laurent您使用CPAN中的哪个模块来执行此操作?请使用Config::ini文件并显示您编写的代码以及您希望对配置执行的操作。如果这些服务器部件最终以阵列形式出现,这很重要吗?您是否需要将它们排列整齐?如果已经有多个模块可以执行此操作,为什么要重新发明轮子?@simbabque:for originality、 :)不要重新发明轮子。CPAN模块通常有用于自动测试的测试套件,并且大多可以处理特殊情况。您可以自己重新发明轮子,但当有CPAN模块时,请不要在此处将其用作答案。投票人能否评论我如何改进答案?