Как я могу получить доступ к INI-файлам из Perl?

#perl #config #ini

#perl #config #ini

Вопрос:

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

Комментарии:

1. Лучший способ — посмотреть на CPAN ( search.cpan.org ). 🙂

Ответ №1:

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

Комментарии:

1. Config::IniFiles — это очень мощный INI-менеджер. Хорошая рекомендация.

Ответ №2:

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

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

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

Комментарии:

1. «Лучшие практики Perl» не рекомендуют использовать tie.

Ответ №3:

Лучший способ — использовать доступные модули в 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
  

Комментарии:

1. Обратите внимание, что этот анализатор сохранит только одну пару ключ / значение для каждого раздела.

2. Perl best practice рекомендует НЕ использовать regex для чтения файлов конфигурации, а использовать стандартные модули из CPAN… Для ini-файлов: Config::IniFiles .

Ответ №4:

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

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

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

Ответ №5:

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

Ответ №6:

Придираться к вышесказанному:

Tie::Cfg, загруженный из CPAN, не обрабатывает разделы и ключи, в которых могут быть пробелы. Ее необходимо изменить, добавив кавычки («) вокруг «ключей» при настройке хэш-записей как для раздела, так и для ключей внутри разделов. Файлы, которые я пытаюсь прочитать, были сгенерированы пользователями 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);
  

Комментарии:

1. Зачем изобретать велосипед?

2. возможно, разработчик не имеет доступа к установочному пакету или не настраивает или использует другой пакет, затем использует функцию для работы.