There are some elements of your code which suggest that you haven't fully grasped Perl data structures. The main ones that struck me originally were:
$info{$name}{$fruit}{path} = $p; $path=$info{$name}{$fruit}{path}; $name=$info{name}{$fruit}{$path};
Notice that in some places you have 'name' instead of $name, and 'path' instead of $path. Take a look at the "Data extracted:", from my output below, to gain a bit more insight into this. Also, I recommend that you read "perldsc - Perl Data Structures Cookbook".
You input data is idealised. It contains nothing to exercise the code that skips comments and blank lines. I've added some additional records:
$ cat test_input.txt Albert apple /path/to/somewhere/a # next line is <TAB><TAB><NL> Jack pineapple /path/to/somewhere/b # next line is only space characters Jack apple /path/to/somewhere/c # Comments only work when # is first character! Dex jackfruit /path/to/somewhere/d # next line is blank
And, to reveal the types of whitespace (^I is a tab; $ is a newline):
$ cat -vet test_input.txt Albert apple /path/to/somewhere/a$ # next line is <TAB><TAB><NL>$ ^I^I$ Jack pineapple /path/to/somewhere/b$ # next line is only space characters$ $ Jack apple /path/to/somewhere/c$ # Comments only work when # is first character!$ Dex jackfruit /path/to/somewhere/d$ # next line is blank$ $
This would have alerted you to a problem in your regex (\s+ should be \s*). When you've got the basic code working, you should add new records with the wrong number of fields, and validation code to deal with such. There may be any number of other checks you may wish to implement; for instance, using pathname as an example: is the format valid? is it a real file? can it be read? is it the right type of file? and so on.
There's another issue with your input file format. Real names and real fruits can contain spaces. How do you deal with that? A tab-separated CSV file, or similar, might be a better option than plain text.
You haven't shown any expected output, so we don't know what you want. I've already pointed out problems with "$path=..." and "$name=...". Also, trying to access that data using a list of fruits seems very strange. Knowing what output you wanted, would put us in a better position to steer you towards a solution.
Here's some code to get you started:
#!/usr/bin/env perl use strict; use warnings; use autodie; my $input_file = 'test_input.txt'; my $info = parse_input_file($input_file); #get $address for each line in input file # Assume "path", not "address". # Will only be for each "processed" line: # no comments or blanks. #get $name for each line in input file # Again, will only be for each "processed" line: # no comments or blanks. # You also seemed to want a list of fruits. my (@names, @fruits, @paths, %seen); for my $name (keys %$info) { push @names, $name; FRUIT: for my $fruit (keys %{$info->{$name}}) { push @paths, $info->{$name}{$fruit}; next FRUIT if $seen{$fruit}++; push @fruits, $fruit; } } # TODO - for demo only; remove for production use Data::Dump; print "Data extracted:\n"; dd $info; print "Names:\n"; dd \@names; print "Fruits:\n"; dd \@fruits; print "Paths:\n"; dd \@paths; sub parse_input_file { my ($file) = @_; my $info = {}; { open my $fh, '<', $file; while (<$fh>) { next if /^(?:#|\s*$)/; my ($name, $fruit, $path) = split; $info->{$name}{$fruit} = $path; } } return $info; }
Here's the output from a sample run:
Data extracted: { Albert => { apple => "/path/to/somewhere/a" }, Dex => { jackfruit => "/path/to/somewhere/d" }, Jack => { apple => "/path/to/somewhere/c", pineapple => "/path/to/somewhere/b", }, } Names: ["Jack", "Dex", "Albert"] Fruits: ["apple", "pineapple", "jackfruit"] Paths: [ "/path/to/somewhere/c", "/path/to/somewhere/b", "/path/to/somewhere/d", "/path/to/somewhere/a", ]
Also, consider registering a username. There are currently over 100,000 posts by "Anonymous Monk"; for now, you're easily lost in a very large crowd. There's other benefits, such as being able to edit your posts. It's very simple: see "Create A New User".
— Ken
In reply to Re: Perl parse text file using hash
by kcott
in thread Perl parse text file using hash
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |