Come posso accedere al file INI da Perl?
Domanda
Qual è il modo migliore per analizzare il file INI in Perl e la conversione di hash?
Soluzione
Io preferisco usare Config :: IniFiles modulo.
Altri suggerimenti
Se vi piace lo stile più la Perl quindi provare Tie::Cfg
. Esempio:
tie my %conf, 'Tie::Cfg', READ => "/etc/connect.cfg";
$conf{test}="this is a test";
Il modo migliore è quello di utilizzare i moduli disponibili in CPAN come quello che gli altri hanno suggerito.Qui sotto è solo per la vostra comprensione, diciamo che hanno un file ini come questo:
$ more test.ini
[Section1]
s1tag1=s1value1 # some comments
[Section2]
s2tag1=s2value1 # some comments
s2tag2=s2value2
[Section3]
s3tag1=s3value1
si può fare la propria analisi w/o moduli di Perl regex (o metodi string) + strutture dati come hash.
Codice Di Esempio:
$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";
}
uscita
$ perl perl.pl
Section1 => s1tag1
Section1 => s1value1
Section3 => s3tag1
Section3 => s3value1
Section2 => s2tag2
Section2 => s2value2
Config :: Piccolo è molto facile e semplice da usare.
$Config = Config::Tiny->read( 'file.conf' );
my $one = $Config->{section}->{one};
my $Foo = $Config->{section}->{Foo};
Prova questo modulo da CPAN: Config :: :: INI Reader
Nitpicking di quanto sopra:
Tie :: Cfg, come scaricati da CPAN, non gestisce le sezioni e le chiavi che possono avere spazi in loro. Ha bisogno di essere cambiato con l'aggiunta di virgolette ( ") attorno le 'chiavi' per impostare le voci di hash sia per la sezione e le chiavi all'interno delle sezioni. I file che sto cercando di leggere sono state generate da gente MS Windows' e, quindi, hanno un sacco di spazi per andare in giro.
Config :: minuscole, Config :: IniFiles sono pignolo sul formato. Se una linea non è di forma [sezione] o il tasto = val, si genera un errore e non si può raggiungere gli hash, che, almeno in Config :: file, vengono riempiti in modo corretto in ogni caso. Sarebbe bello avere un'opzione errore di ignorare. I file che sto cercando di leggere avere alcune linee M4 spuri in esso, che ho potuto correre attraverso m4 per sbarazzarsi di, ma che non è necessario in quello che sto cercando di fare con questo particolare script.
la lettura e la scrittura di funzione per modificare file 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;
}
Utilizzo di esempio:
leggere il file conf e salvato hash
$conf = iniRead("/etc/samba/smb.conf");
cambiare il vostro attributo di config o aggiunti nuovi attributi di configurazione
modifica
$conf->{"global"}->{"workgroup"} = "WORKGROUP";
aggiunto nuova config
$conf->{"www"}->{"path"}="/var/www/html";
salvato la nuova configurazione nel file
iniWrite("/etc/samba/smb.conf",$conf);