Beefy Boxes and Bandwidth Generously Provided by pair Networks RobOMonk
We don't bite newbies here... much
 
PerlMonks  

assigning to a hash via split

by aardvark (Pilgrim)
on Feb 19, 2001 at 01:43 UTC ( [id://59325]=perlquestion: print w/replies, xml ) Need Help??

This is an archived low-energy page for bots and other anonmyous visitors. Please sign up if you are a human and want to interact.

aardvark has asked for the wisdom of the Perl Monks concerning the following question:

Happy Sunday Everybody,
Is there a way to assign to a hash via split?
Here's what I've got so far:

sub read_passwd { open IN, '/etc/passwd' or die "can't open IN $!\n"; my %users; my @fields = qw(name pword uid gid fullname home shell); while (<IN>) { chomp; my %rec; my @data = split(/:/); $rec{$fields[0]} = $data[0]; $rec{$fields[1]} = $data[1]; $rec{$fields[2]} = $data[2]; $rec{$fields[3]} = $data[3]; $rec{$fields[4]} = $data[4]; $rec{$fields[5]} = $data[5]; $rec{$fields[6]} = $data[6]; $users{$rec{name}} = \%rec; } return (\%users); }
Does anybody know of a better way to do this?
Specifically, is there a way to assign to %rec during the split?
Then, if I add another field all I have to do is add it to @fields.

I really want less typing (Laziness, Impatience) so I can have more time to work on my Hubris. ;-)

Get Strong Together!!

Replies are listed 'Best First'.
Re: assigning to a hash via split
by danger (Priest) on Feb 19, 2001 at 01:48 UTC

    You can use a hash-slice to assign a list of values to a list of keys directly. Your inner while loop becomes:

    while (<IN>) { chomp; my %rec; @rec{@fields} = split /:/; $users{$rec{name}} = \%rec; }
Re: assigning to a hash via split
by japhy (Canon) on Feb 19, 2001 at 01:49 UTC
    Sure. Here's some short code for you:
    while (<IN>) { chomp; my ($name) = /([^:]+)/; @{ $users{$name} }{ @fields } = split /:/; }
    I basically create the hash reference and assign to it all at once.
    update: down with temporary variables, up with one-liners.
    chomp(@{$users{(/([^:]+)/)[0]}}{@fields} = split /:/) while <IN>;


    japhy -- Perl and Regex Hacker
Re: assigning to a hash via split
by BlueLines (Hermit) on Feb 19, 2001 at 02:19 UTC
    You mayt also want to check out getpwent, which handles the iteration over the passwd(5) file and removes the need for the split (and open) in the first place.

    BlueLines

    Disclaimer: This post may contain inaccurate information, be habit forming, cause atomic warfare between peaceful countries, speed up male pattern baldness, interfere with your cable reception, exile you from certain third world countries, ruin your marriage, and generally spoil your day. No batteries included, no strings attached, your mileage may vary.
      Ooh, good catch. You get a ++ from me, and I offer this in reply:
      sub buildUserHash { use User::pwent; my %users; while (my $obj = getpwent) { $users{$obj->name} = $obj } return \%users; }
      Now, you have a hash of User::pwent objects.

      japhy -- Perl and Regex Hacker
(dkubb) Re: (2) Parsing the /etc/passwd file
by dkubb (Deacon) on Feb 19, 2001 at 02:24 UTC

    There is an easier way to do what you want, using a CPAN module called Unix::PasswdFile:

    use Unix::PasswdFile; my $pw = Unix::PasswdFile->new('/etc/passwd') or die 'Could not open /etc/passwd'; my %users = map { $_ => [$ps->user($_)] } $pw->users;

    This will create the %users hash without you needing to worry about the structure of the /etc/passwd file.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://59325]
Approved by root
help
Sections?
Information?
Find Nodes?
Leftovers?
    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.