Perl 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

我必须将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 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[]
  • 返回的数组元素包含
    引号字符

以下是我使用Config:ini文件所做的工作:

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模块时,请不要在此处将其用作答案。投票人能否评论我如何改进答案?