Load file into a hash
am 06.10.2007 13:04:16 von Bill H
Is there a "perl" way of loading a file directly into a hash instead
of using something like this quick example:
open(FILE,"test.txt");
while()
{
$line = $_;
chop $line;
@dbf = split(/\t/,$line);
$MYHASH{$dbf[0]} = $dbf[1];
}
close(FILE);
where the text file contains entries like this:
NAME0\tsome value
NAME1\tanother value
etc... ?
Bill H
Re: Load file into a hash
am 06.10.2007 13:19:06 von Mark Clements
Bill H wrote:
> Is there a "perl" way of loading a file directly into a hash instead
> of using something like this quick example:
>
> open(FILE,"test.txt");
> while()
> {
> $line = $_;
> chop $line;
> @dbf = split(/\t/,$line);
> $MYHASH{$dbf[0]} = $dbf[1];
> }
> close(FILE);
>
> where the text file contains entries like this:
>
> NAME0\tsome value
> NAME1\tanother value
>
C:\TEMP>cat loadarray.pl
#!perl
use strict;
use warnings;
use Data::Dumper;
my $filename = shift;
open my $fh,"<",$filename or die $!;
my %hash = map { chomp; split /\t/ } <$fh>;
print Dumper(\%hash);
close $fh or die $!;
C:\TEMP>cat data.txt
UK London
France Paris
Italy Rome
USA Washington
Germany Berlin
C:\TEMP>loadarray.pl data.txt
$VAR1 = {
'France' => 'Paris',
'UK' => 'London',
'Italy' => 'Rome',
'Germany' => 'Berlin',
'USA' => 'Washington'
};
C:\TEMP>
Mark
Re: Load file into a hash
am 06.10.2007 13:32:27 von Bill H
On Oct 6, 7:19 am, Mark Clements
wrote:
> Bill H wrote:
> > Is there a "perl" way of loading a file directly into a hash instead
> > of using something like this quick example:
>
> > open(FILE,"test.txt");
> > while()
> > {
> > $line = $_;
> > chop $line;
> > @dbf = split(/\t/,$line);
> > $MYHASH{$dbf[0]} = $dbf[1];
> > }
> > close(FILE);
>
> > where the text file contains entries like this:
>
> > NAME0\tsome value
> > NAME1\tanother value
>
> C:\TEMP>cat loadarray.pl
> #!perl
>
> use strict;
> use warnings;
>
> use Data::Dumper;
>
> my $filename = shift;
> open my $fh,"<",$filename or die $!;
>
> my %hash = map { chomp; split /\t/ } <$fh>;
>
> print Dumper(\%hash);
>
> close $fh or die $!;
>
> C:\TEMP>cat data.txt
> UK London
> France Paris
> Italy Rome
> USA Washington
> Germany Berlin
>
> C:\TEMP>loadarray.pl data.txt
> $VAR1 = {
> 'France' => 'Paris',
> 'UK' => 'London',
> 'Italy' => 'Rome',
> 'Germany' => 'Berlin',
> 'USA' => 'Washington'
> };
>
> C:\TEMP>
>
> Mark- Hide quoted text -
>
> - Show quoted text -
I like that Mark. You basically took everything I had in the while
loop and put it on one line. Nice and neat.
Bill H
Re: Load file into a hash
am 06.10.2007 16:06:18 von nobull67
On Oct 6, 12:19 pm, Mark Clements
wrote:
> my %hash = map { chomp; split /\t/ } <$fh>;
That works but is very fragile - one bad line can screw all your data
from then on.
I prefer (the canonical idiom)
my %hash = map { /(.*?)\t(.*)/ } <$fh>;
This will ignore lines with no "\t" in them. Do something vaguely
reasonable with lines containing more than one "\t". Oh, and it's
shorter too.
Re: Load file into a hash
am 06.10.2007 16:11:56 von nobull67
On Oct 6, 3:06 pm, Brian McCauley wrote:
>
> my %hash = map { /(.*?)\t(.*)/ } <$fh>;
Oh, and since we're slurping the file anyhow we can save a few lines
by using File::Slurp
use File::Slurp;
my %hash = map { /(.*?)\t(.*)/ } read_file('test.txt');
Re: Load file into a hash
am 06.10.2007 22:36:07 von Martijn Lievaart
On Sat, 06 Oct 2007 14:06:18 +0000, Brian McCauley wrote:
> On Oct 6, 12:19 pm, Mark Clements
> wrote:
>> my %hash = map { chomp; split /\t/ } <$fh>;
>
> That works but is very fragile - one bad line can screw all your data
> from then on.
>
> I prefer (the canonical idiom)
>
> my %hash = map { /(.*?)\t(.*)/ } <$fh>;
>
> This will ignore lines with no "\t" in them. Do something vaguely
> reasonable with lines containing more than one "\t". Oh, and it's
> shorter too.
Doesn't that include the newline on any line in the second field?
M4
Re: Load file into a hash
am 06.10.2007 23:36:40 von Tad McClellan
Martijn Lievaart wrote:
> On Sat, 06 Oct 2007 14:06:18 +0000, Brian McCauley wrote:
>> my %hash = map { /(.*?)\t(.*)/ } <$fh>;
> Doesn't that include the newline on any line in the second field?
Which part of the regex can match those newlines?
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
Re: Load file into a hash
am 06.10.2007 23:36:41 von Tad McClellan
Bill H wrote:
> Is there a "perl" way of loading a file directly into a hash instead
> of using something like this quick example:
>
> open(FILE,"test.txt");
You should always, yes *always*, check the return value from open().
> while()
> {
> $line = $_;
If you want it in $line, then put it there, rather than put it
somewhere else and then move it there:
while ( my $line = )
> chop $line;
You should use chomp() to remove newlines.
my %myhash = split /[\t\n]/, do{ local $/; };
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
Re: Load file into a hash
am 07.10.2007 09:53:51 von Martijn Lievaart
On Sat, 06 Oct 2007 21:36:40 +0000, Tad McClellan wrote:
> Martijn Lievaart wrote:
>> On Sat, 06 Oct 2007 14:06:18 +0000, Brian McCauley wrote:
>
>
>>> my %hash = map { /(.*?)\t(.*)/ } <$fh>;
>
>
>> Doesn't that include the newline on any line in the second field?
>
>
> Which part of the regex can match those newlines?
You're right. '.' does not match newlines. Stupid me.
M4
Re: Load file into a hash
am 09.10.2007 23:16:57 von Uri Guttman
>>>>> "BM" == Brian McCauley writes:
BM> On Oct 6, 3:06 pm, Brian McCauley wrote:
>>
>> my %hash = map { /(.*?)\t(.*)/ } <$fh>;
BM> Oh, and since we're slurping the file anyhow we can save a few lines
BM> by using File::Slurp
BM> use File::Slurp;
BM> my %hash = map { /(.*?)\t(.*)/ } read_file('test.txt');
i was going to chime in with slurp as well. :)
i have a better and faster idiom for slurping files into hashes
(untested for typos):
my %hash = read_file('test.txt') =~ /^([^\t]+)\t(.*)$/gm ;
and for most config type files slurping is fast since they are likely
smaller than even the OS's I/O block size which can be 64k or even
256k. there is no savings using perl's i/o system and reading many files
line by line. it is a great teaching technique but it is slower than
slurping in a whole file and parsing it in one regex call (as is
possible in many cases).
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org