2010-01-06 64 views
14

在Perl中解析INI文件並將其轉換爲散列的最佳方式是什麼?如何從Perl訪問INI文件?

+5

最好的辦法是看CPAN(http://search.cpan.org)。 :) – 2010-01-07 13:49:28

回答

21

我更喜歡使用Config::IniFiles模塊。

+1

Config :: IniFiles是一個非常強大的INI管理器。好的建議。 – daotoad 2010-01-06 22:33:34

9

如果您想了解更多Perlish的風格,那麼嘗試Tie::Cfg。樣品:

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

$conf{test}="this is a test"; 
+1

建議不要使用領帶,以免被「Perl最佳實踐」使用。 – 2014-12-18 12:50:59

8

Config::Tiny是非常容易和直接使用。

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

my $one = $Config->{section}->{one}; 
my $Foo = $Config->{section}->{Foo}; 
9

最好的方法是使用CPAN中的可用模塊,如其他人所建議的那樣。下面是隻爲你自己的理解,讓我們說你已經INI文件是這樣的:

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

,你可以只用Perl的正則表達式(或字符串的方法)+數據結構,如哈希做自己的分析W/O模塊。

示例代碼:

$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 
+1

請注意,此解析器將僅保留每個部分的一個鍵/值對。 – Thelema 2013-03-29 21:54:48

+0

Perl最佳實踐不推薦使用regex來讀取配置文件,而是使用CPAN的標準模塊...對於ini文件:'Config :: IniFiles'。 – 2014-12-18 12:51:48

1

吹毛求疵以上:

領帶:: CFG,從CPAN下載,不處理部分和密鑰,可能有在他們的空間。它需要通過在「鍵」周圍添加引號(「)來改變,當設置段和段內的鍵的哈希條目時,我試圖讀取的文件是由MS Windows的人員生成的,因此有足夠的空間去處理

Config :: Tiny,Config :: IniFiles格式化如果任何行不是[section]或key = val形式,它們會拋出一個錯誤,無法進入哈希,至少在Config :: Files中,無論如何都是正確填充的,最好有一個忽略錯誤選項,我試圖讀取的文件中有一些虛假的M4行,我可以通過m4運行來擺脫,但這不是我試圖用這個特定的腳本所必需的。

0

讀取和寫入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文件並保存到哈希

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

改變你的配置屬性或添加新的配置屬性

編輯

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

添加新的配置

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

保存新的配置到文件

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

爲什麼要重新發明輪子? – Toto 2014-10-17 09:36:52

+0

也許開發人員不能訪問安裝軟件包或不配置或使用其他軟件包,然後使用該功能進行工作。 – mehrdad 2014-10-18 07:19:28