¿Cómo puedo acceder a los archivos INI de Perl?
Pregunta
¿Cuál es la mejor manera de analizar el archivo INI en Perl y convertirlo en un hash?
Solución
Yo prefiero usar Config :: IniFiles módulo.
Otros consejos
Si te gusta el estilo más perlish luego tratar Tie::Cfg
. Muestra:
tie my %conf, 'Tie::Cfg', READ => "/etc/connect.cfg";
$conf{test}="this is a test";
La mejor manera es hacer uso de módulos disponibles en CPAN como lo que otros han sugerido. A continuación es sólo para su propia comprensión, digamos que usted tiene ini como esto:
$ more test.ini
[Section1]
s1tag1=s1value1 # some comments
[Section2]
s2tag1=s2value1 # some comments
s2tag2=s2value2
[Section3]
s3tag1=s3value1
que puede hacer su propio análisis w / o módulos utilizando sólo expresiones regulares de Perl (o métodos de cadena) + estructuras de datos como hashes.
Código de ejemplo:
$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";
}
salida
$ perl perl.pl
Section1 => s1tag1
Section1 => s1value1
Section3 => s3tag1
Section3 => s3value1
Section2 => s2tag2
Section2 => s2value2
Config :: Tiny es muy fácil y sencillo de usar.
$Config = Config::Tiny->read( 'file.conf' );
my $one = $Config->{section}->{one};
my $Foo = $Config->{section}->{Foo};
Trate de este módulo de CPAN: Config :: :: INI lector
nitpicking en lo anterior:
Tie :: cfg, como descargar desde CPAN, no maneja secciones y claves que pueden tener espacios en ellos. Se necesita ser cambiado añadiendo comillas ( ") en torno a las 'claves' al configurar las entradas de hash, tanto para la sección y las claves dentro de las secciones. Los archivos que estoy tratando de leer fueron generados por la gente de MS Windows', y por lo tanto tienen un montón de espacios para todos.
Config :: Tiny, Config :: IniFiles son exigentes sobre el formato. Si cualquier línea no es de la forma [sección] o la tecla = val, se emite un error y no se puede llegar a los hashes, que, al menos en Config :: Archivos, se rellenan correctamente todos modos. Sería bueno tener una opción de error de ignorar. Los archivos que estoy tratando de leer tiene algunas líneas M4 espurios en él, que podía correr a través de m4 para quitarse de encima, pero eso no es necesario en lo que yo estoy tratando de hacer con este script en particular.
lectura y escritura para la función de edición de archivos 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;
}
ejemplos de uso:
leer archivo de configuración y se guardan en un hash
$conf = iniRead("/etc/samba/smb.conf");
cambiar la configuración de su atributo o añadido nuevos atributos de configuración
editar
$conf->{"global"}->{"workgroup"} = "WORKGROUP";
añadido nuevo config
$conf->{"www"}->{"path"}="/var/www/html";
guardado su nueva configuración en el archivo
iniWrite("/etc/samba/smb.conf",$conf);