Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Re^2: Parse a file into a hash

by kazak (Beadle)
on Apr 05, 2012 at 20:21 UTC ( #963733=note: print w/replies, xml ) Need Help??

in reply to Re: Parse a file into a hash
in thread [Resolved] Parse a file into a hash

Thank you for your reply, yes it helped a bit. File I need to parse is a .csv file with a fileds that must be converted to an ACLs, there are two fields: User name , asset name . One user can have either one or multiple asset names, but user name is unique. So unique user name I'm trying to use as a key and asset names I trying to use as a values of these unique keys. So one user John Doe may have either one asset name: John Doe = { "KJhkh23"} or multiple: John Doe = { "KJhkh23", "0jUfh4631",....."N"}. File was populated manually and irregulary, I mean in "User Name" field we may have one name "John Doe" but in field " Asset name" we may have a column of values. The problem is to define a first field as a key(John Doe) and the second as a value (KJhkh23), and if on the next line we can't detect a key, assume that this asset belongs to last available key (John Doe) . I'm new to perl so this code may look like a total mess for coders.
#!/usr/bin/perl -w use warnings; use strict; my @tmp; ### Start Configuration my $src_file = "Servers.csv"; ### End Configuration my %stack = (); my $current_key = undef; my $current_value = undef; open( SRC, "<", $src_file ); while (<SRC>) { chomp; s/#.*//; s/\"//g; s/\;/\-/; push @tmp, $_ if $_ =~ m/^\;/ and next; my ($key,$value) = split /\-/, $_; push @tmp, $value; if (defined $key) { $current_key = $key; push @tmp, $value; $stack{$current_key} = @tmp; } close(SRC);

Replies are listed 'Best First'.
Re^3: Parse a file into a hash
by aaron_baugher (Curate) on Apr 05, 2012 at 22:19 UTC

    You should probably show us some sample data, so we can tell what "can't detect a key" means. But in general, you're talking about creating a hash of arrays. So for every key/value pair, you'll want to do something like this:

    push @{$stack{$key}}, $value;

    That pushes the value onto the array referenced by the key within the hash. Later, you'll be able to go through them with:

    for my $key (keys %stack){ for my $value (@{$stack{$key}}){ # do stuff with $key and $value } }

    Aaron B.
    My Woefully Neglected Blog, where I occasionally mention Perl.

      Thanks for your reply. I don't know how to preserve initial format of the file here, so I'll replace empty cells of.csv with null.

      Username; Asset Name

      Corinna Mayer;JKDef4574

      Janek Huska;NAdf8f48g5

      Eric Shtits;JSd5345kPFl



      Erik Fisher;UiO8trve

      As you can see Eric Shtits owns 3 asset names in according to this .csv file, so two fields that supposed to be keys are empty.And I need to implement a solution that will be able to detect that all three asset names belong to one person. Regards, Kazak

        hi check if this code works or not its not tested.

        my ($key,$val,$keyprev); open(fh,'< file.txt'); while (<fh>){ $keyprev=$key; ($key,$val)=split /\;/, $_; $key=$keyprev if($key eq""); print "$key :: $val\n"; } close fh;

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://963733]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (12)
As of 2018-06-21 10:04 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (118 votes). Check out past polls.