IniFiles使用数组或哈希

时间:2017-02-14 11:18:59

标签: 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 3"
...
SRV4 = "server n"

这在CPAN中并不清楚。

对于第一个变体,我可以遍历哈希并使用while循环读取我的值,或者如果我删除编号一致的项目,我不必小心。

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

3 个答案:

答案 0 :(得分:1)

您可以直接使用您的ini文件,但有一些曲折。

根据docs

  

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

     

返回部分中指定参数($ parameter)的值   $ section,如果没有section或no,则返回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[]用于参数名称。
  • 并且返回的数组元素包含"引号字符。

答案 1 :(得分:0)

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

如果您不需要“服务器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>

现在你有两种选择,你可以按照自己的意愿行事。

这是脚本:它的逻辑是:如果line匹配'server'然后处理并提取值并存储在hash和array中,否则跳过。

#!/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 ;

答案 2 :(得分:0)

以下是我使用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"

感谢您的贡献! 问候 劳伦