Reputation: 389
I'm trying to read in a multi-line config file with records into a perl hash array
Example Config File:
record_1
phone=5551212
data=1234234
end_record_1
record_2
people_1=bob
people_2=jim
data=1234
end_record_2
record_3
people_1=sue
end_record_3
here's what I'm looking for:
$myData{1}{"phone"} <--- 5551212
$myData{1}{"data"} <--- 1234234
$myData{2}{"people_1"} <--- bob
... etc
What's the best way to read this in? Module? Regex with multi-line match? Brute force? I'm up in the air on where to head next.
Upvotes: 1
Views: 2187
Reputation: 316
There are a number of modules for this, so the best practice is (as usual) to use them rather than re-invent the wheel.
From the snippet of the config file you posted, it looks like Config::Simple
may be the best choice. If you can simplify the config format, then Config::Tiny
would be easier to use. If things get more complicated, then you may have to use Config::General
.
http://metacpan.org/pod/Config::Tiny
http://metacpan.org/pod/Config::Simple
http://metacpan.org/pod/Config::General
Upvotes: 1
Reputation: 6204
Here's one option with your data set:
use strict;
use warnings;
use Data::Dumper;
my %hash;
{
local $/ = '';
while (<DATA>) {
my ($rec) = /record_(\d+)/;
$hash{$rec}{$1} = $2 while /(\S+)=(.+)/g;
}
}
print Dumper \%hash;
__DATA__
record_1
phone=5551212
data=1234234
end_record_1
record_2
people_1=bob
people_2=jim
data=1234
end_record_2
record_3
people_1=sue
end_record_3
Output:
$VAR1 = {
'1' => {
'data' => '1234234',
'phone' => '5551212'
},
'3' => {
'people_1' => 'sue'
},
'2' => {
'people_1' => 'bob',
'data' => '1234',
'people_2' => 'jim'
}
};
Setting local $/ = ''
results in an empty line being treated as a "record separator" in your data set, so we can use regexs on those records to grab the information for the hash keys/values.
Hope this helps!
Upvotes: 8
Reputation: 63481
Read it in one line at a time.
When you see a new record, add a new empty associative array to myData
and grab a reference to it - this will be your "current record".
Now when you see key/value pairs on a line, you can add that to the current record array (if there is one)
When you see the end of a record, you just clear the reference to the current record.
Upvotes: 0