Creating multiple hashes from multiple files in one go









up vote
0
down vote

favorite












I want to perform a vlookup like process but with multiple files wherein the contents of the first column from all files (sorted n uniq-ed) is reference value. Now I would like to store these key-values pairs from each file in each hash and then print them together. Something like this:



file1: while()$hash1$key=$val...file2: while()$hash2$key=$val...file3: while()$hash3$key=$val...so on



Then print it: print "$ref_val $hash1$ref_val $hash3$ref_val $hash3$ref_val..."



$i=1;
@FILES = @ARGV;
foreach $file(@FILES)

open($fh,$file);
$hname="hash".$i; ##trying to create unique hash by attaching a running number to hash name
while(<$fh>)@d=split("t");$hname$d[0]=$d[7];$i++;

$set=$i-1; ##store this number for recreating the hash names during printing

open(FH,"ref_list.txt");
while(<FH>)

chomp();print "$_t";
## here i run the loop recreating the hash names and printing its corresponding value
for($i=1;$i<=$set;$i++)$hname="hash".$i; print "$hname$_t";
print "n";



Now this where I am stuck perl takes $hname as hash name instead of $hash1, $hash2...



Thanks in advance for the helps and opinions










share|improve this question























  • You are trying to use symbolic reference, to create variable names dynamically; it's only trouble and (almost) never necessary. Why not simply put references to those hashes in an array?
    – zdim
    22 hours ago










  • The hash is made with key of the first element ($d[0]) and value of ... the eight-th ($d[7]) -- is that intended?
    – zdim
    22 hours ago










  • @zdim...yes, correctly understood. Each line has 10 columns, but i need to form the hash out of column 1 (key) and column 7 (value)....yes that symbolic reference aspect did come, but i wasn't sure how to apply it here... :(
    – SangramJB
    22 hours ago










  • OK, thank you. The symbolic reference business -- you don't want it. Just don't do it. Now, your explanation says that "contents of the first column from all files (sorted n uniq-ed) is reference value" -- how is that? The "first column" from all files is a long list of values, how is that a reference? Can you show a sample?
    – zdim
    22 hours ago










  • OK...now i have files like : exp1.txt, exp2.txt, exp3.txt so on. To collect and create a list of all reference values I do this : cut -f 1 *.txt | sort | uniq > ref_list.txt
    – SangramJB
    22 hours ago














up vote
0
down vote

favorite












I want to perform a vlookup like process but with multiple files wherein the contents of the first column from all files (sorted n uniq-ed) is reference value. Now I would like to store these key-values pairs from each file in each hash and then print them together. Something like this:



file1: while()$hash1$key=$val...file2: while()$hash2$key=$val...file3: while()$hash3$key=$val...so on



Then print it: print "$ref_val $hash1$ref_val $hash3$ref_val $hash3$ref_val..."



$i=1;
@FILES = @ARGV;
foreach $file(@FILES)

open($fh,$file);
$hname="hash".$i; ##trying to create unique hash by attaching a running number to hash name
while(<$fh>)@d=split("t");$hname$d[0]=$d[7];$i++;

$set=$i-1; ##store this number for recreating the hash names during printing

open(FH,"ref_list.txt");
while(<FH>)

chomp();print "$_t";
## here i run the loop recreating the hash names and printing its corresponding value
for($i=1;$i<=$set;$i++)$hname="hash".$i; print "$hname$_t";
print "n";



Now this where I am stuck perl takes $hname as hash name instead of $hash1, $hash2...



Thanks in advance for the helps and opinions










share|improve this question























  • You are trying to use symbolic reference, to create variable names dynamically; it's only trouble and (almost) never necessary. Why not simply put references to those hashes in an array?
    – zdim
    22 hours ago










  • The hash is made with key of the first element ($d[0]) and value of ... the eight-th ($d[7]) -- is that intended?
    – zdim
    22 hours ago










  • @zdim...yes, correctly understood. Each line has 10 columns, but i need to form the hash out of column 1 (key) and column 7 (value)....yes that symbolic reference aspect did come, but i wasn't sure how to apply it here... :(
    – SangramJB
    22 hours ago










  • OK, thank you. The symbolic reference business -- you don't want it. Just don't do it. Now, your explanation says that "contents of the first column from all files (sorted n uniq-ed) is reference value" -- how is that? The "first column" from all files is a long list of values, how is that a reference? Can you show a sample?
    – zdim
    22 hours ago










  • OK...now i have files like : exp1.txt, exp2.txt, exp3.txt so on. To collect and create a list of all reference values I do this : cut -f 1 *.txt | sort | uniq > ref_list.txt
    – SangramJB
    22 hours ago












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I want to perform a vlookup like process but with multiple files wherein the contents of the first column from all files (sorted n uniq-ed) is reference value. Now I would like to store these key-values pairs from each file in each hash and then print them together. Something like this:



file1: while()$hash1$key=$val...file2: while()$hash2$key=$val...file3: while()$hash3$key=$val...so on



Then print it: print "$ref_val $hash1$ref_val $hash3$ref_val $hash3$ref_val..."



$i=1;
@FILES = @ARGV;
foreach $file(@FILES)

open($fh,$file);
$hname="hash".$i; ##trying to create unique hash by attaching a running number to hash name
while(<$fh>)@d=split("t");$hname$d[0]=$d[7];$i++;

$set=$i-1; ##store this number for recreating the hash names during printing

open(FH,"ref_list.txt");
while(<FH>)

chomp();print "$_t";
## here i run the loop recreating the hash names and printing its corresponding value
for($i=1;$i<=$set;$i++)$hname="hash".$i; print "$hname$_t";
print "n";



Now this where I am stuck perl takes $hname as hash name instead of $hash1, $hash2...



Thanks in advance for the helps and opinions










share|improve this question















I want to perform a vlookup like process but with multiple files wherein the contents of the first column from all files (sorted n uniq-ed) is reference value. Now I would like to store these key-values pairs from each file in each hash and then print them together. Something like this:



file1: while()$hash1$key=$val...file2: while()$hash2$key=$val...file3: while()$hash3$key=$val...so on



Then print it: print "$ref_val $hash1$ref_val $hash3$ref_val $hash3$ref_val..."



$i=1;
@FILES = @ARGV;
foreach $file(@FILES)

open($fh,$file);
$hname="hash".$i; ##trying to create unique hash by attaching a running number to hash name
while(<$fh>)@d=split("t");$hname$d[0]=$d[7];$i++;

$set=$i-1; ##store this number for recreating the hash names during printing

open(FH,"ref_list.txt");
while(<FH>)

chomp();print "$_t";
## here i run the loop recreating the hash names and printing its corresponding value
for($i=1;$i<=$set;$i++)$hname="hash".$i; print "$hname$_t";
print "n";



Now this where I am stuck perl takes $hname as hash name instead of $hash1, $hash2...



Thanks in advance for the helps and opinions







perl hash






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 22 hours ago

























asked 22 hours ago









SangramJB

105




105











  • You are trying to use symbolic reference, to create variable names dynamically; it's only trouble and (almost) never necessary. Why not simply put references to those hashes in an array?
    – zdim
    22 hours ago










  • The hash is made with key of the first element ($d[0]) and value of ... the eight-th ($d[7]) -- is that intended?
    – zdim
    22 hours ago










  • @zdim...yes, correctly understood. Each line has 10 columns, but i need to form the hash out of column 1 (key) and column 7 (value)....yes that symbolic reference aspect did come, but i wasn't sure how to apply it here... :(
    – SangramJB
    22 hours ago










  • OK, thank you. The symbolic reference business -- you don't want it. Just don't do it. Now, your explanation says that "contents of the first column from all files (sorted n uniq-ed) is reference value" -- how is that? The "first column" from all files is a long list of values, how is that a reference? Can you show a sample?
    – zdim
    22 hours ago










  • OK...now i have files like : exp1.txt, exp2.txt, exp3.txt so on. To collect and create a list of all reference values I do this : cut -f 1 *.txt | sort | uniq > ref_list.txt
    – SangramJB
    22 hours ago
















  • You are trying to use symbolic reference, to create variable names dynamically; it's only trouble and (almost) never necessary. Why not simply put references to those hashes in an array?
    – zdim
    22 hours ago










  • The hash is made with key of the first element ($d[0]) and value of ... the eight-th ($d[7]) -- is that intended?
    – zdim
    22 hours ago










  • @zdim...yes, correctly understood. Each line has 10 columns, but i need to form the hash out of column 1 (key) and column 7 (value)....yes that symbolic reference aspect did come, but i wasn't sure how to apply it here... :(
    – SangramJB
    22 hours ago










  • OK, thank you. The symbolic reference business -- you don't want it. Just don't do it. Now, your explanation says that "contents of the first column from all files (sorted n uniq-ed) is reference value" -- how is that? The "first column" from all files is a long list of values, how is that a reference? Can you show a sample?
    – zdim
    22 hours ago










  • OK...now i have files like : exp1.txt, exp2.txt, exp3.txt so on. To collect and create a list of all reference values I do this : cut -f 1 *.txt | sort | uniq > ref_list.txt
    – SangramJB
    22 hours ago















You are trying to use symbolic reference, to create variable names dynamically; it's only trouble and (almost) never necessary. Why not simply put references to those hashes in an array?
– zdim
22 hours ago




You are trying to use symbolic reference, to create variable names dynamically; it's only trouble and (almost) never necessary. Why not simply put references to those hashes in an array?
– zdim
22 hours ago












The hash is made with key of the first element ($d[0]) and value of ... the eight-th ($d[7]) -- is that intended?
– zdim
22 hours ago




The hash is made with key of the first element ($d[0]) and value of ... the eight-th ($d[7]) -- is that intended?
– zdim
22 hours ago












@zdim...yes, correctly understood. Each line has 10 columns, but i need to form the hash out of column 1 (key) and column 7 (value)....yes that symbolic reference aspect did come, but i wasn't sure how to apply it here... :(
– SangramJB
22 hours ago




@zdim...yes, correctly understood. Each line has 10 columns, but i need to form the hash out of column 1 (key) and column 7 (value)....yes that symbolic reference aspect did come, but i wasn't sure how to apply it here... :(
– SangramJB
22 hours ago












OK, thank you. The symbolic reference business -- you don't want it. Just don't do it. Now, your explanation says that "contents of the first column from all files (sorted n uniq-ed) is reference value" -- how is that? The "first column" from all files is a long list of values, how is that a reference? Can you show a sample?
– zdim
22 hours ago




OK, thank you. The symbolic reference business -- you don't want it. Just don't do it. Now, your explanation says that "contents of the first column from all files (sorted n uniq-ed) is reference value" -- how is that? The "first column" from all files is a long list of values, how is that a reference? Can you show a sample?
– zdim
22 hours ago












OK...now i have files like : exp1.txt, exp2.txt, exp3.txt so on. To collect and create a list of all reference values I do this : cut -f 1 *.txt | sort | uniq > ref_list.txt
– SangramJB
22 hours ago




OK...now i have files like : exp1.txt, exp2.txt, exp3.txt so on. To collect and create a list of all reference values I do this : cut -f 1 *.txt | sort | uniq > ref_list.txt
– SangramJB
22 hours ago












1 Answer
1






active

oldest

votes

















up vote
1
down vote













The shown code attempts to use symbolic references to construct variable names at runtime. Those things can raise a lot of trouble and should not be used, except very occasionally in very specialized code.



Here is a way to read multiple files, each into a hash, and store them for later processing.



use warnings;
use strict;
use feature 'say';

use Data::Dump qw(dd);

my @files = @ARGV;

my @data;
for my $file (@files)
open my $fh, '<', $file or do
warn "Skip $file, can't open it: $!";
next;
;
push @data, map (split /t/, $_)[0,6] <$fh> ;


dd @data;


Each hash associates the first column with the seventh (index 6), as clarified, for each line. A reference to such a hash for each file, formed by , is added to the array.



Note that when you add a key-value pair to a hash which already has that key the new overwrites the old. So if a string repeats in the first column in a file, the hash for that file will end up with the value (column 7) for the last one. The OP doesn't discuss possible duplicates of this kind in data files (only for the reference file), please clarify if needed.



The Data::Dump is used only to print; if you don't wish to install it use core Data::Dumper.



I am not sure that I get the use of that "reference file", but you can now go through the array of hash references for each file and fetch values as needed. Perhaps like



open my $fh_ref, '<', $ref_file or die "Can't open $ref_file: $!";

while (my $line = <$fh_ref>)

my $key = ... # retrieve the key from $line
print "$key: ";

foreach my $hr (@data)
print "$hr->$key ";

say '';



This will print key: followed by values for that string, one from each file.






share|improve this answer






















  • @SangramJB Edited code (it was splitting on any space, from my tests, now it uses tab), and added some notes.
    – zdim
    21 hours ago











  • you aren't using @files in your code
    – showaltb
    9 hours ago










  • @showaltb Ah, thank you -- fixed
    – zdim
    9 hours ago










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237394%2fcreating-multiple-hashes-from-multiple-files-in-one-go%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote













The shown code attempts to use symbolic references to construct variable names at runtime. Those things can raise a lot of trouble and should not be used, except very occasionally in very specialized code.



Here is a way to read multiple files, each into a hash, and store them for later processing.



use warnings;
use strict;
use feature 'say';

use Data::Dump qw(dd);

my @files = @ARGV;

my @data;
for my $file (@files)
open my $fh, '<', $file or do
warn "Skip $file, can't open it: $!";
next;
;
push @data, map (split /t/, $_)[0,6] <$fh> ;


dd @data;


Each hash associates the first column with the seventh (index 6), as clarified, for each line. A reference to such a hash for each file, formed by , is added to the array.



Note that when you add a key-value pair to a hash which already has that key the new overwrites the old. So if a string repeats in the first column in a file, the hash for that file will end up with the value (column 7) for the last one. The OP doesn't discuss possible duplicates of this kind in data files (only for the reference file), please clarify if needed.



The Data::Dump is used only to print; if you don't wish to install it use core Data::Dumper.



I am not sure that I get the use of that "reference file", but you can now go through the array of hash references for each file and fetch values as needed. Perhaps like



open my $fh_ref, '<', $ref_file or die "Can't open $ref_file: $!";

while (my $line = <$fh_ref>)

my $key = ... # retrieve the key from $line
print "$key: ";

foreach my $hr (@data)
print "$hr->$key ";

say '';



This will print key: followed by values for that string, one from each file.






share|improve this answer






















  • @SangramJB Edited code (it was splitting on any space, from my tests, now it uses tab), and added some notes.
    – zdim
    21 hours ago











  • you aren't using @files in your code
    – showaltb
    9 hours ago










  • @showaltb Ah, thank you -- fixed
    – zdim
    9 hours ago














up vote
1
down vote













The shown code attempts to use symbolic references to construct variable names at runtime. Those things can raise a lot of trouble and should not be used, except very occasionally in very specialized code.



Here is a way to read multiple files, each into a hash, and store them for later processing.



use warnings;
use strict;
use feature 'say';

use Data::Dump qw(dd);

my @files = @ARGV;

my @data;
for my $file (@files)
open my $fh, '<', $file or do
warn "Skip $file, can't open it: $!";
next;
;
push @data, map (split /t/, $_)[0,6] <$fh> ;


dd @data;


Each hash associates the first column with the seventh (index 6), as clarified, for each line. A reference to such a hash for each file, formed by , is added to the array.



Note that when you add a key-value pair to a hash which already has that key the new overwrites the old. So if a string repeats in the first column in a file, the hash for that file will end up with the value (column 7) for the last one. The OP doesn't discuss possible duplicates of this kind in data files (only for the reference file), please clarify if needed.



The Data::Dump is used only to print; if you don't wish to install it use core Data::Dumper.



I am not sure that I get the use of that "reference file", but you can now go through the array of hash references for each file and fetch values as needed. Perhaps like



open my $fh_ref, '<', $ref_file or die "Can't open $ref_file: $!";

while (my $line = <$fh_ref>)

my $key = ... # retrieve the key from $line
print "$key: ";

foreach my $hr (@data)
print "$hr->$key ";

say '';



This will print key: followed by values for that string, one from each file.






share|improve this answer






















  • @SangramJB Edited code (it was splitting on any space, from my tests, now it uses tab), and added some notes.
    – zdim
    21 hours ago











  • you aren't using @files in your code
    – showaltb
    9 hours ago










  • @showaltb Ah, thank you -- fixed
    – zdim
    9 hours ago












up vote
1
down vote










up vote
1
down vote









The shown code attempts to use symbolic references to construct variable names at runtime. Those things can raise a lot of trouble and should not be used, except very occasionally in very specialized code.



Here is a way to read multiple files, each into a hash, and store them for later processing.



use warnings;
use strict;
use feature 'say';

use Data::Dump qw(dd);

my @files = @ARGV;

my @data;
for my $file (@files)
open my $fh, '<', $file or do
warn "Skip $file, can't open it: $!";
next;
;
push @data, map (split /t/, $_)[0,6] <$fh> ;


dd @data;


Each hash associates the first column with the seventh (index 6), as clarified, for each line. A reference to such a hash for each file, formed by , is added to the array.



Note that when you add a key-value pair to a hash which already has that key the new overwrites the old. So if a string repeats in the first column in a file, the hash for that file will end up with the value (column 7) for the last one. The OP doesn't discuss possible duplicates of this kind in data files (only for the reference file), please clarify if needed.



The Data::Dump is used only to print; if you don't wish to install it use core Data::Dumper.



I am not sure that I get the use of that "reference file", but you can now go through the array of hash references for each file and fetch values as needed. Perhaps like



open my $fh_ref, '<', $ref_file or die "Can't open $ref_file: $!";

while (my $line = <$fh_ref>)

my $key = ... # retrieve the key from $line
print "$key: ";

foreach my $hr (@data)
print "$hr->$key ";

say '';



This will print key: followed by values for that string, one from each file.






share|improve this answer














The shown code attempts to use symbolic references to construct variable names at runtime. Those things can raise a lot of trouble and should not be used, except very occasionally in very specialized code.



Here is a way to read multiple files, each into a hash, and store them for later processing.



use warnings;
use strict;
use feature 'say';

use Data::Dump qw(dd);

my @files = @ARGV;

my @data;
for my $file (@files)
open my $fh, '<', $file or do
warn "Skip $file, can't open it: $!";
next;
;
push @data, map (split /t/, $_)[0,6] <$fh> ;


dd @data;


Each hash associates the first column with the seventh (index 6), as clarified, for each line. A reference to such a hash for each file, formed by , is added to the array.



Note that when you add a key-value pair to a hash which already has that key the new overwrites the old. So if a string repeats in the first column in a file, the hash for that file will end up with the value (column 7) for the last one. The OP doesn't discuss possible duplicates of this kind in data files (only for the reference file), please clarify if needed.



The Data::Dump is used only to print; if you don't wish to install it use core Data::Dumper.



I am not sure that I get the use of that "reference file", but you can now go through the array of hash references for each file and fetch values as needed. Perhaps like



open my $fh_ref, '<', $ref_file or die "Can't open $ref_file: $!";

while (my $line = <$fh_ref>)

my $key = ... # retrieve the key from $line
print "$key: ";

foreach my $hr (@data)
print "$hr->$key ";

say '';



This will print key: followed by values for that string, one from each file.







share|improve this answer














share|improve this answer



share|improve this answer








edited 40 mins ago

























answered 21 hours ago









zdim

30.9k32040




30.9k32040











  • @SangramJB Edited code (it was splitting on any space, from my tests, now it uses tab), and added some notes.
    – zdim
    21 hours ago











  • you aren't using @files in your code
    – showaltb
    9 hours ago










  • @showaltb Ah, thank you -- fixed
    – zdim
    9 hours ago
















  • @SangramJB Edited code (it was splitting on any space, from my tests, now it uses tab), and added some notes.
    – zdim
    21 hours ago











  • you aren't using @files in your code
    – showaltb
    9 hours ago










  • @showaltb Ah, thank you -- fixed
    – zdim
    9 hours ago















@SangramJB Edited code (it was splitting on any space, from my tests, now it uses tab), and added some notes.
– zdim
21 hours ago





@SangramJB Edited code (it was splitting on any space, from my tests, now it uses tab), and added some notes.
– zdim
21 hours ago













you aren't using @files in your code
– showaltb
9 hours ago




you aren't using @files in your code
– showaltb
9 hours ago












@showaltb Ah, thank you -- fixed
– zdim
9 hours ago




@showaltb Ah, thank you -- fixed
– zdim
9 hours ago

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237394%2fcreating-multiple-hashes-from-multiple-files-in-one-go%23new-answer', 'question_page');

);

Post as a guest














































































Popular posts from this blog

Top Tejano songwriter Luis Silva dead of heart attack at 64

政党

天津地下鉄3号線