Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

file tree to hash

by Anonymous Monk
on Apr 05, 2003 at 21:59 UTC ( #248343=perlquestion: print w/replies, xml ) Need Help??

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

I have a directory tree that is being provided in the form of a flat text file.

/root/dir1/file1
/root/dir1/file2
/root/dir1/file3
/root/dir2/file1


What I would like to do is create a hash out of this information. (note: this file could be of any length and have a variable directory depth)
hash{root}{dir1}{file1} = $value (where $value is determined at run time)

My initial thought was to split each line into an array, and then use the information in node_id=196317 to turn the array into the hash. But this seems less than optimal.

What would be the best way to handle this problem?

Replies are listed 'Best First'.
Re: file tree to hash
by dakkar (Hermit) on Apr 05, 2003 at 22:15 UTC
    #!/usr/bin/perl -w use Data::Dumper; {my $i=1; sub makevalue { return $i++; } } my $hash={};my $h0; my $l;my @c; while ($l=<DATA>) { $h0=$hash; @c=split '/',$l; for my $c (@c[0..$#c-1]) { next unless $c; $h0=($h0->{$c}||={}); } $h0->{$c[-1]}=makevalue($l); } print Dumper($hash); __DATA__ /root/dir1/file1 /root/dir1/file2 /root/dir1/file3 /root/dir2/file1

    Outputs:

    $VAR1 = { 'root' => { 'dir2' => { 'file1' => 4 }, 'dir1' => { 'file2' => 2, 'file3' => 3, 'file1' => 1 } } };

    What does it do: it splits each row, and walks down the HoH (creating empty hashes as needed), putting the computed values (in this example just a counter) on the leaf.

    I think this is more or less what you were describing, but I can't come up with a better solution.

    -- 
            dakkar - Mobilis in mobile
    
Re: file tree to hash
by pg (Canon) on Apr 06, 2003 at 00:09 UTC
    This is one way, less conventional:
    use strict; use Data::Dumper; my %hash; while (<DATA>) { chomp; s/\//}{/g; eval "\$hash".substr($_,1,length)."} = undef"; } print Dumper(\%hash); __DATA__ /root/dir1/file1 /root/dir1/file2 /root/dir1/file3 /root/dir2/file1
Re: file tree to hash
by chromatic (Archbishop) on Apr 05, 2003 at 22:09 UTC

    That's how I would do it. Why does it seem less than optimal? What do you mean by "best"?

Re: file tree to hash
by DrManhattan (Chaplain) on Apr 06, 2003 at 02:40 UTC

    Here's another eval() solution.

    #!/usr/bin/perl use strict; use Data::Dumper; my %hash; my $value = "determined at run time"; while (<DATA>) { chomp; eval '$hash{' . join( "}{", split(/\//) ) . "} = '$value'"; } print Dumper(\%hash); __DATA__ root/dir1/file1 root/dir1/file2 root/dir1/file3 root/dir2/file1
    Edit: merlyn is correct. Don't ever use this. A file named "root/dir1/file1}=1;`someprogram`;$hash{foo" could be used to execute an external program.

    -Matt

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://248343]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2023-06-01 15:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?