tags:

views:

8921

answers:

3

Given the following file:

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

I use the following to load the file into a Perl hash:

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

The result, however, is as follows:

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

How can I load the above file into a hash with, say,

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

Thanks.

+8  A: 

Here you go:

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

This walks through every line splitting on the '=' sign and either adds an entry or appends to an existing entry in the hash table.

Nikhil
Thanks. Just inserted chomp($val). Works like a charm. :)
A: 

Can you add some code to your map function to check for the existence of a hash entry and append the new value?

I haven't done Perl in a while, but when I did something like this in the past, I read the file in line by line (while $inputLine = <FILE>) and used split on '=' to load the hash with additional checks to see if the hash already had that key, appending if the entry already existed.

Mark
+4  A: 

If you have control over the data file, consider switching from a custom format to something like YAML. This gives you a lot of power out of the box without having to hack your custom format more and more. In particular, multiple keys creating a list is non-obvious. YAML's way of doing it is much clearer.

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

Note also that YAML allows you to sculpt the key/value pairs so they line up for easier reading.

And the code to parse it is done by a module, YAML::XS being the best of the bunch.

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

print Dumper Load scalar read_file(shift);

And the data structure looks like so:

$VAR1 = {
          'department' => [
                            'foo',
                            'bar'
                          ],
          'location' => [
                          'baz',
                          'biff'
                        ],
          'name' => 'Wally Jones'
        };
Schwern
Code reuse is a good thing.
Brad Gilbert