Как я могу получить доступ к файлам INI из Perl? - PullRequest
14 голосов
/ 06 января 2010

Как лучше всего проанализировать INI-файл в Perl и преобразовать его в хэш?

Ответы [ 7 ]

22 голосов
/ 06 января 2010

Я предпочитаю использовать модуль Config :: IniFiles .

9 голосов
/ 07 января 2010

Лучший способ - использовать доступные модули в 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
9 голосов
/ 06 января 2010

Если вам больше нравится стиль perlish, попробуйте Tie::Cfg. Пример:

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

$conf{test}="this is a test";
8 голосов
/ 06 января 2010

Config :: Tiny очень прост и понятен в использовании.

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

my $one = $Config->{section}->{one};
my $Foo = $Config->{section}->{Foo};
7 голосов
/ 06 января 2010

Попробуйте этот модуль из CPAN: Config :: INI :: Reader

1 голос
/ 17 октября 2014

функция чтения и записи для редактирования 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 = iniRead("/etc/samba/smb.conf");

изменить атрибут конфигурации или добавить новые атрибуты конфигурации

редактировать

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

добавлен новый конфиг

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

сохранил вашу новую конфигурацию в файл

iniWrite("/etc/samba/smb.conf",$conf);
1 голос
/ 12 апреля 2013

Нажми на вышеперечисленное:

Tie :: Cfg, загруженный из CPAN, не обрабатывает разделы и ключи, в которых могут быть пробелы. Его нужно изменить, добавив кавычки (") вокруг" ключей "при настройке хеш-записей как для раздела, так и для ключей в разделах. Файлы, которые я пытаюсь прочитать, были сгенерированы людьми из MS Windows, и поэтому есть много мест для прогулок.

Config :: Tiny, Config :: IniFiles суетливо относятся к формату. Если какая-либо строка не имеет форму [section] или key = val, они выдают ошибку, и никто не может получить хэши, которые, по крайней мере в Config :: Files, правильно заполнены в любом случае. Было бы неплохо иметь опцию игнорирования ошибок. В файлах, которые я пытаюсь прочитать, есть несколько ложных строк M4, от которых я мог бы пробежаться через m4, но это не является необходимым в том, что я пытаюсь сделать с этим конкретным сценарием.

...