IniFiles 使用数组或散列

IniFiles use array or hash

我必须将 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 循环读取我的值,如果我删除了编号一致的项目,我就不必担心。

欢迎任何提示!提前谢谢你。

如果您熟悉一点正则表达式,也可以逐行读取文件并存储所需的值。我在下面的示例中使用了它。

如果您不需要 "server 1"、"server 2".. 值的特定顺序,那么您可以使用 Hash,否则,请使用数组。

此处,根据您的示例,一个示例测试文件:

%_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 ;
      push (@array, ) ;
    }
  }
}

print Dumper %hash ;
print Dumper @array ;

您可以直接使用您的 ini-file,但要稍加改动。

根据 docs:

val ($section, $parameter [, $default] )

Returns the value of the specified parameter ($parameter) in section $section, returns undef (or $default if specified) if no section or no parameter for the given section exists.

If you want a multi-line/value field returned as an array, just specify an array as the receiver:

@values = $cfg->val('Section', 'Parameter');

A multi-line/value field that is returned in a scalar context will be joined using $/ (input record separator, default is \n) if defined, otherwise the values will be joined using \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:IniFiles 为我所做的工作:

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"

感谢您的贡献! 问候 洛朗