Pergunta

O que é a melhor maneira de analisar o arquivo INI em Perl e convertê-lo em haxixe?

Foi útil?

Solução

Eu prefiro usar Config :: IniFiles módulo.

Outras dicas

Se você gosta de estilo mais perlish tente Tie::Cfg . Amostra:

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

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

A melhor maneira é fazer uso de módulos disponíveis no CPAN como o que os outros têm sugerido. Abaixo é apenas para o seu próprio entendimento, digamos que você tem ini assim:

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

Você pode fazer sua própria análise w / o módulos usando apenas regex do Perl (ou string métodos) + estruturas de dados como hashes.

Exemplo de código:

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

saída

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

Config :: minúsculo é muito fácil e simples de usar.

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

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

Tente este módulo do CPAN: Config :: INI :: Leitor

picuinhas sobre o acima:

Tie :: Cfg, como baixado do CPAN, não manipula seções e chaves que podem ter espaços. Ele precisa ser alterado pela adição de aspas ( ") em torno das 'chaves' ao definir as entradas de hash tanto para a seção e as chaves dentro das seções. Os arquivos que eu estou tentando ler foram gerados por pessoas do MS Windows', e, assim, tem abundância de espaços para ir ao redor.

Config :: minúsculo, Config :: IniFiles espalhafatoso sobre o formato. Se qualquer linha não é da forma [seção] ou key = val, eles lançar um erro e não se pode chegar aos hashes, que, pelo menos em Config :: Files, são preenchidos corretamente de qualquer maneira. Seria bom ter uma opção de erro ignorar. Os arquivos que eu estou tentando ler tem algumas linhas M4 espúrias nele, que eu pudesse correr através M4 para se livrar de, mas isso não é necessário no que eu estou tentando fazer com este script particular.

função de gravação para editar ini leitura e:

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

uso de amostra:

arquivo conf leitura e salva de hash

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

alterar o atributo sua configuração ou adicionados novos atributos de configuração

editar

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

adicionada nova configuração

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

salvou sua nova configuração para o arquivo

iniWrite("/etc/samba/smb.conf",$conf);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top