2008-10-24 32 views
10

Dado el siguiente archivo:¿Cómo cargo un archivo en un hash Perl?

department=value1 
location=valueA 
location=valueB 
department=value2 

utilizo el siguiente para cargar el archivo en un hash de Perl:

use File::Slurp; 
use Data::Dumper; 
my %hash = map { 
    s/#.*//; 
    s/^\s+//; 
    s/\s+$//; 
    m/(.*?)\s*=\s*(.*)/; 
} read_file($file); 
print Dumper(\%hash); 

El resultado, sin embargo, es el siguiente:

$VAR1 = { 
      'location' => 'valueB', 
      'department' => 'value2' 
     }; 

¿Cómo puedo cargar el archivo anterior en un hash con, por ejemplo,

$VAR1 = { 
      'location' => 'valueA,valueB', 
      'department' => 'value1,value2' 
     }; 

Gracias.

Respuesta

20

Aquí van:

my %hash; 
while (<FILE>) 
{ 
    chomp; 
    my ($key, $val) = split /=/; 
    $hash{$key} .= exists $hash{$key} ? ",$val" : $val; 
} 

Esta guía a través de cada división de línea en el signo '=' y, o bien se añade una entrada o añade a una entrada existente en la tabla hash.

+0

Gracias. Acabo de insertar chomp ($ val). Funciona de maravilla. :) –

+0

Cuando pruebo en Windows con Perl 5.12.1, los valores siempre tienen una coma anterior ... Tengo que cambiar la última declaración en una if-conditional completa. –

-1

¿Puede agregar algún código a la función del mapa para verificar la existencia de una entrada hash y agregar el nuevo valor?

No he usado Perl por un tiempo, pero cuando hice algo como esto en el pasado, leo el archivo en línea por línea (mientras $ inputLine = <ARCHIVO>) y uso split en '=' para cargue el hash con comprobaciones adicionales para ver si el hash ya tenía esa clave, anexando si la entrada ya existía.

5

Si tiene control sobre el archivo de datos, considere cambiar de un formato personalizado a algo así como YAML. Esto le proporciona una gran cantidad de energía sin tener que hackear su formato personalizado cada vez más. En particular, las claves múltiples que crean una lista no son obvias. La forma de hacerlo de YAML es mucho más clara.

name:  Wally Jones 
department: [foo, bar] 
location: [baz, biff] 

Tenga en cuenta también que YAML le permite esculpir los pares de clave/valor para que se alineen para facilitar la lectura.

Y el código para analizarlo se hace por un módulo, YAML::XS siendo el mejor del grupo.

use File::Slurp; 
use YAML::XS; 
use Data::Dumper; 

print Dumper Load scalar read_file(shift); 

Y la estructura de datos se ve así:

$VAR1 = { 
      'department' => [ 
          'foo', 
          'bar' 
          ], 
      'location' => [ 
          'baz', 
          'biff' 
         ], 
      'name' => 'Wally Jones' 
     }; 
+0

La reutilización de código es algo bueno. –

+0

la línea imprimir Dumper Load scalar read_file (shift); parece sospechoso. ¿Falta el doblecolon? – gorn

+0

@gorn Es correcto. 'Dumper()' de Data :: Dumper, 'Load()' de YAML :: XS, 'escalar' está integrado y' read_file() 'de File :: Slurp. Con los parens se ve como 'print (Dumper (Load (escalar (read_file (shift)))))' y es por eso que dejé los parens. – Schwern

Cuestiones relacionadas