in reply to newbie hasher

Or you could write a one-liner to transform the input file into a hash.

Method 1 - (map with 'short-circuit', now handles empty lines)
use strict; use Data::Dumper; # Uh, well spotted, typo fixed with the extra + # which would have no effect anyway. :-) # ysth suggested that putting () in map shortcircuts # empty lines. It worked. Thanks. :-) # Wow, even better, dropped that testing bit. #my %hostlist = map { /^(\w+)\s(.*)/?($1,$2):() } (<DATA>); my %hostlist = map { /^(\w+)\s(.*)/ } (<DATA>); print Dumper(\%hostlist); __DATA__ host1 1.1.1.1 host2 1.2.3.5
Method 2 - Better approach
use strict; use Data::Dumper; my %hostlist; { local $/; %hostlist = <DATA> =~ /^(\w+)\s(.*)/gm; } print Dumper(\%hostlist); __DATA__ host1 1.1.1.1 host2 1.2.3.5
Updated: added the 3rd method after seen jonadab's suggestion. Here's my solution of capturing a real host file.

Method 3 - Capture from the /etc/host file
use strict; use Data::Dumper; my %hosts; while (<DATA>) { next if /^\s*(?:#|$)/; # ignore comments and empty lines /^([^\s#]+)\s+(.*)/; # capture ip address and names $hosts{$_} = $1 foreach split /\s+/, $2; } print Dumper(\%hosts); __DATA__ # IP Masq gateway: 192.168.0.80 pedestrian # Primary desktop: 192.168.0.82 raptor1 # Family PC upstairs: 192.168.0.84 trex tyrannosaur family # Domain servers: 205.212.123.10 dns1 brutus 208.140.2.15 dns2 156.63.130.100 dns3 cherokee
And the output -
$VAR1 = { 'dns3' => '156.63.130.100', 'brutus' => '205.212.123.10', 'raptor1' => '192.168.0.82', 'trex' => '192.168.0.84', 'cherokee' => '156.63.130.100', 'dns1' => '205.212.123.10', 'tyrannosaur' => '192.168.0.84', 'dns2' => '208.140.2.15', 'family' => '192.168.0.84', 'pedestrian' => '192.168.0.80' };

Replies are listed 'Best First'.
Re: Re: newbie hasher
by prodevel (Scribe) on Nov 20, 2003 at 05:45 UTC
    By no means am I discounting the other methods, but I really like this one-liner due to my haphazzard knowledge of regex:

    %hostlist = <DATA> =~ /^(\w+)+\s(.*)/gm;

    This is exactly what I was looking for even though I was no where near explicit about what I wanted.

    I'm already applying this method to a few more scripts. The map was cool too.

    I am somewhat curious as to the extensive use of Data::Dumper instead of print-ing %hash?

    Thanks all!
      I am somewhat curious as to the extensive use of Data::Dumper instead of print-ing %hash?
      Just shows the structure better, and shows up any undefs, tabs, newlines, wide characters, unprintable characters, etc. that sneak into your data better.
Re^2: newbie hasher
by Coruscate (Sexton) on Nov 20, 2003 at 05:43 UTC

    Look at your first regex again. /^(\w+)+/ looks quite funny :) aww he decided to remove the double '+'ing :(

    Anyhow... just another way of writing the regex:

    my %hotlist = map { m#\A(\S+)\s+(.*)\z#; $1 => $2 } <DATA>;

Re: Re: newbie hasher
by davis (Vicar) on Nov 20, 2003 at 09:59 UTC
    my %hostlist = map { /^(\w+)\s(.*)/; $1 => $2 } (<DATA>);
    should be....
    my %hostlist = map { /^(\w+)\s+(.*)/; $1 => $2 } (<DATA>);
    (extra + after the whitespace metachar)

    davis
    It's not easy to juggle a pregnant wife and a troubled child, but somehow I managed to fit in eight hours of TV a day.