How can I access INI files from Perl?

∥☆過路亽.° 提交于 2019-11-28 23:25:56

I prefer to use Config::IniFiles module.

Ivan Nevostruev

If you like more perlish style then try Tie::Cfg. Sample:

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

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

The best way is to make use of available modules in CPAN as what others have suggested. Below is just for your own understanding, let's say you have ini file like this:

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

you can do your own parsing w/o modules by using just Perl's regex (or string methods) + data structures like hashes.

Sample Code:

   $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";
    }

output

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

Config::Tiny is very easy and straightforward to use.

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

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

Try this module from CPAN: Config::INI::Reader

Nitpicking on the above:

Tie::Cfg, as downloaded from CPAN, does not handle sections and keys that may have spaces in them. It needs to be changed by adding quotes (") around the "keys" when setting the hash entries for both the section and the keys within the sections. The files I'm trying to read were generated by MS Windows' folks, and thus have plenty of spaces to go around.

Config::Tiny, Config::IniFiles are fussy about the format. If any line is not of the form [section] or key=val, they throw an error and one can't get to the hashes, which, at least in Config::Files, are filled in properly anyway. It would be nice to have an ignore error option. The files I'm trying to read have some spurious M4 lines in it, that I could run through m4 to get rid of, but that is not necessary in what I'm trying to do with this particular script.

reading and write function for ini file edit:

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;
}

sample usage:

read conf file and saved to hash

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

change the your config attribute or added new config attributes

edit

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

added new config

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

saved your new configuration to file

iniWrite("/etc/samba/smb.conf",$conf);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!