如何从 Perl 访问 INI 文件?

Posted

技术标签:

【中文标题】如何从 Perl 访问 INI 文件?【英文标题】:How can I access INI files from Perl? 【发布时间】:2011-01-02 03:50:04 【问题描述】:

在 Perl 中解析 INI 文件并将其转换为哈希的最佳方法是什么?

【问题讨论】:

最好的方法是查看 CPAN (search.cpan.org)。 :) 【参考方案1】:

从 CPAN 试试这个模块:Config::INI::Reader

【讨论】:

【参考方案2】:

如果您更喜欢 perlish 风格,请尝试Tie::Cfg。示例:

tie my %conf, 'Tie::Cfg', READ => "/etc/connect.cfg";

$conftest="this is a test";

【讨论】:

“Perl 最佳实践”建议不要使用 tie。【参考方案3】:

Config::Tiny 使用起来非常简单直接。

$Config = Config::Tiny->read( 'file.conf' );

my $one = $Config->section->one;
my $Foo = $Config->section->Foo;

【讨论】:

【参考方案4】:

我更喜欢使用Config::IniFiles 模块。

【讨论】:

Config::IniFiles 是一个非常强大的 INI 管理器。很好的推荐。【参考方案5】:

最好的方法是按照其他人的建议使用 CPAN 中的可用模块。下面只是为了你自己的理解,假设你有这样的ini文件:

$ more test.ini
[Section1]
    s1tag1=s1value1             # some comments
[Section2]
    s2tag1=s2value1           # some comments
    s2tag2=s2value2
[Section3]
    s3tag1=s3value1

您可以通过仅使用 Perl 的正则表达式(或字符串方法)+ 哈希等数据结构来进行自己的不带模块的解析。

示例代码:

   $ini="test.ini";
    open (INI, "$ini") || die "Can't open $ini: $!\n";
        while (<INI>) 
            chomp;
            if (/^\s*\[(\w+)\].*/) 
                $section = $1;
            
            if (/^\W*(\w+)=?(\w+)\W*(#.*)?$/) 
                $keyword = $1;
                $value = $2 ;
                # put them into hash
                $hash$section = [ $keyword, $value];
            
        
    close (INI);
    while( my( $k, $v ) = each( %hash ) ) 
        print "$k => " . $hash$k->[0]."\n";
        print "$k => " . $hash$k->[1]."\n";
    

输出

$ perl perl.pl
Section1 => s1tag1
Section1 => s1value1
Section3 => s3tag1
Section3 => s3value1
Section2 => s2tag2
Section2 => s2value2

【讨论】:

请注意,此解析器只会为每个部分保留一个键/值对。 Perl 最佳实践建议不要使用正则表达式来读取配置文件,而是使用 CPAN 中的标准模块...对于 ini 文件:Config::IniFiles【参考方案6】:

对上面的挑剔:

从 CPAN 下载的 Tie::Cfg 不处理其中可能包含空格的部分和键。在为部分和部分中的键设置哈希条目时,需要通过在“键”周围添加引号(“)来更改它。我试图读取的文件是由 MS Windows 的人生成的,因此有很多地方可以去。

Config::Tiny, Config::IniFiles 对格式很挑剔。如果任何行不是 [section] 或 key=val 的形式,它们就会抛出错误,并且无法访问散列,至少在 Config::Files 中,无论如何都正确填写了散列。有一个忽略错误选项会很好。我尝试读取的文件中有一些虚假的 M4 行,我可以通过 m4 运行以摆脱这些行,但在我尝试使用此特定脚本执行的操作中,这不是必需的。

【讨论】:

【参考方案7】:

ini文件编辑读写功能:

sub iniRead
  
  my $ini = $_[0];
  my $conf;
  open (INI, "$ini") || die "Can't open $ini: $!\n";
    while (<INI>) 
        chomp;
        if (/^\s*\[\s*(.+?)\s*\]\s*$/) 
            $section = $1;
        

        if ( /^\s*([^=]+?)\s*=\s*(.*?)\s*$/ ) 
          $conf->$section->$1 = $2;         
        
    
  close (INI);
  return $conf;

sub iniWrite

  my $ini = $_[0];
  my $conf = $_[1];
  my $contents = '';
foreach my $section ( sort  (($b eq '_') <=> ($a eq '_')) || ($a cmp $b)  keys %$conf ) 
    my $block = $conf->$section;
    $contents .= "\n" if length $contents;
    $contents .= "[$section]\n" unless $section eq '_';
    foreach my $property ( sort keys %$block ) 
      $contents .= "$property=$block->$property\n";
    
  
  open( CONF,"> $ini" ) or print("not open the file");
  print CONF $contents;
  close CONF;

示例用法:

读取conf文件并保存到hash

$conf = iniRead("/etc/samba/smb.conf");

更改您的配置属性或添加新的配置属性

编辑

$conf->"global"->"workgroup" = "WORKGROUP";

添加了新配置

$conf->"www"->"path"="/var/www/html";

将您的新配置保存到文件中

iniWrite("/etc/samba/smb.conf",$conf);

【讨论】:

为什么要重新发明***? 可能开发者没有权限安装包或者没有配置或使用其他包,然后使用该功能工作。

以上是关于如何从 Perl 访问 INI 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何从我的CPanel访问php.ini?

如何访问服务器的 php.ini 文件?

如何调试从 PHP 文件调用的 Perl

Perl - 如何从文本文件中省略行?

在 Perl 中,如何从文件中删除 ^M?

如何删除从perl读取sql文件时附加的特殊字符