CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
How to Print the Value of a key in multilevel hash

 



Tejas
User

Aug 27, 2014, 11:22 PM

Post #1 of 21 (3564 views)
How to Print the Value of a key in multilevel hash Can't Post

Below is my code

Code
#! /usr/bin/perl 

my $pwd = `pwd`;
chomp($pwd);
my $final_output= "$pwd/$Match_Unmatched_data.txt";
my $temp_file = "$pwd/CTO_TRANSACTIONS_TEMP1";
my $clr_txns= "$pwd/Txns_In_CLR1.txt";
open (CLR_OUTPUT,"< $clr_txns")or die "could not open $clr_txns $!";
open (CTO_OUTPUT,"< $temp_file")or die "could not open $cto_txns $!";
open (Final_Out,"> $final_output")or die "could not open $final_output$!";


my %hash= ();
while (my $line = <CTO_OUTPUT>) {
chomp $line;
my ($cid,$date,$etid,$esid,$amount,$curr,$com_code,$ppcl_id,$dsid) = (split /\|/, $line)[1,2,3,4,5,6,7,8,9];
$hash{$cid}{$date}{$etid}{$esid}{$amount}{$curr}{$com_code}{$ppcl_id}{$dsid} = 1;
}

while (my $line2 = <CLR_OUTPUT>){
chomp $line2;
my($cid,$date,$etid,$esid,$amount,$curr,$com_code,$ppcl_id,$dsid) = (split /\|/, $line2)[0,1,2,3,4,5,6,7,8];
if($hash{$cid}{$date}{$etid}{$esid}{$amount}{$curr}{$com_code}{$ppcl_id}{$dsid})
{

print "$date,$amount,{$hash{$cid}},$($hash{$cid}{$date}{$etid}),$hash{$cid}{$date}{$etid}{$esid}{$amount} \n";

delete $hash{$cid}{$date}{$etid}{$esid}{$amount}{$curr}{$com_code}{$ppcl_id}{$dsid}}
else {
print Final_Out "$esid NOT_AVAILABLE\n";

}
}


Iam Trying to Print the values of the key in the middle of multilevel hash, but its printing the address

Quote
print "$date,$amount,{$hash{$cid}},$($hash{$cid}{$date}{$etid}),$hash{$cid}{$date}{$etid}{$esid}{$amount} \n";


Whts wrong here , Or do i need to write the for loop to print each value ?


CTO_TRANSACTIONS_TEMP1

Quote
401879077|7318645|01-JUL-2014|520|1954190|15.27|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879133|8264305|01-JUL-2014|520|1966350|7.59|DAD|2I|1172|14
401879339|6673455|01-JUL-2014|520|1967630|10.99|DAD|2I|1172|14
401879142|611030|01-JUL-2014|520|1983390|1.05|DAD|2I|1172|14
401879125|611030|01-JUL-2014|520|1984030|1.06|DAD|2I|1172|14
401879198|1773481|01-JUL-2014|520|1974670|8.82|DAD|2I|1172|14
401879170|13859405|01-JUL-2014|520|1675310|2.99|DAD|2I|1172|14
401879162|611030|01-JUL-2014|520|1985950|3.99|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14


Txns_In_CLR1.txns

Quote
401879077|7318645|01-JUL-2014|520|1954190|15.27|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879133|8264305|01-JUL-2014|520|1966350|7.59|DAD|2I|1172|14
401879339|6673455|01-JUL-2014|520|1967630|10.99|DAD|2I|1172|14
401879142|611030|01-JUL-2014|520|1983390|1.05|DAD|2I|1172|14
401879125|611030|01-JUL-2014|520|1984030|1.06|DAD|2I|1172|14
401879198|1773481|01-JUL-2014|520|1974670|8.82|DAD|2I|1172|14
401879170|13859405|01-JUL-2014|520|1675310|2.99|DAD|2I|1172|14
401879162|611030|01-JUL-2014|520|1985950|3.99|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14



We can also see that Last txns is available thrice in CTO_TRANSACTIONS_TEMP1 and only once in second file,
It says that this txn is missing in second file,, thts y i have used delete function to delete hash in my code


Thanks
Tejas


Zhris
Enthusiast

Aug 27, 2014, 11:55 PM

Post #2 of 21 (3557 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

Hi,

Perhaps another guru understands your problem better than myself, I have no idea what the desired output you expect is, could you provide this.

Firstly, I think you have possibly approached the problem incorrectly, by building a deep multi level hash, when you probably could have just concatenated all the values together and used that as the key of the root hash. However this depends on what you are really trying to accomplish.

Secondly, when you split the line, you slice the array on different indexes across the two files:

Code
(split /\|/, $line)[1,2,3,4,5,6,7,8,9]; 

(split /\|/, $line2)[0,1,2,3,4,5,6,7,8];

I think the second notation should be used for both. But to be on the safe side the following is sufficient (no slice necessary):

Code
split /\|/, $linen;


Thirdly, In your second while loop, because you test if the deep hash value is already true using your current split values with if($hash{$cid}{$date}{$etid}{$esid}{$amount}{$curr}{$com_code}{$ppcl_id}{$dsid}){, there is probably no need to access the hash at all within this block, you already have all the values in variables, unless of course you want all the keys at a particular level, but I suspect your real intention is something else.

And finally, for example, print "$hash{$cid}" will output the hashes location in memory (address), because its value is another hash, whose keys were defined by you earlier as dates. If you are trying to print i.e. the cid, then print "$cid", or i.e. all the dates, then my @dates = keys %{$hash{$cid}}; print "@dates".

Regards,

Chris


(This post was edited by Zhris on Aug 28, 2014, 12:14 AM)


Tejas
User

Aug 28, 2014, 1:03 AM

Post #3 of 21 (3543 views)
Re: [Zhris] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

When so0me thing i sunmatching the i need to print all the values form file and hash too
Thst why i am printing the hash

AND if u look my print statement o many values of keys
So i have to write the below stmnt so many times for each value to be printed like

Quote

my @dates = keys %{$hash{$cid}}; print "@dates"
my @etid = keys -----
my@ ppcl = keys -----

I was looking for a way to print the values of a nested hash keys in one single statement



Zhris
Enthusiast

Aug 28, 2014, 1:44 AM

Post #4 of 21 (3539 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

Can you please provide expected output based on the input data you provided in your original post.


Quote
I was looking for a way to print the values of a nested hash keys in one single statement


Its not clear what you want the output to look like exactly. Perhaps the output of Data::Dumper Dumper method would be sufficient. Or, here is a recursive function which builds an array of arrays that represents the keys at each level of the hash, this is perhaps what you are looking for:


Code
use strict; 
use warnings;
use Data::Dumper;

my %hash =
(
1 =>
{
a =>
{
foo => 1,
},
b => 1,
},
2 =>
{
c =>
{
bar => 1,
blah => 1,
},
d => 1,
}
);

my $listref = recurse( \%hash );

print Dumper $listref;

$" = ', ';
$, = ' / ';
print map { "@$_" } @$listref;

sub recurse
{
my ( $input, $output, $depth ) = @_;

$output //= [ ];
$depth //= 0;

while ( my ( $key, $value ) = each %$input )
{
push @{$output->[$depth]}, $key;

if ( ref $value eq ref { } )
{
recurse( $value, $output, $depth + 1 );
}
}

return $output;
}


Output:

Code
$VAR1 = [ 
[
'1',
'2'
],
[
'a',
'b',
'c',
'd'
],
[
'foo',
'blah',
'bar'
]
];
1, 2 / a, b, c, d / foo, blah, bar


Regards,

Chris


(This post was edited by Zhris on Aug 28, 2014, 2:39 AM)


Tejas
User

Aug 28, 2014, 3:08 AM

Post #5 of 21 (3525 views)
Re: [Zhris] How to Print the Value of a key in multilevel hash [In reply to] Can't Post


Quote
Its not clear what you want the output to look like exactly. Perhaps the output of Data::Dumper Dumper method would be sufficient. Or, here is a recursive function which builds an array of arrays that represents the keys at each level of the hash, this is perhaps what you are looking for:


1. In a nutshell , iam looking to match each line from first and second file.
2. If a line is available twice in one file and only once in another file , it has to be logged (Its Vice Versa for both files), with the detail that its matching once and its missing once


Hope you gt it

Thanks
Tejas


Zhris
Enthusiast

Aug 28, 2014, 3:49 AM

Post #6 of 21 (3522 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

I think I understand better, but for the third time, please provide your expected output.

Since you haven't provided your expected output nor a detailed enough description ("it has to be logged" isn't clear) I have partially thrown something together. It counts the number of times unique lines occur per file. Is this something you can work from, you can iterate through the resultant hash and handle the data in whatever manner you like.


Code
use strict;  
use warnings;
use Data::Dumper;

my %hash;

my @files = qw/ input.txt input2.txt /;

for my $file ( @files )
{
open my $fh, '<', $file or die "cannot open $file: $!";
while ( my $line = <$fh> )
{
$line =~ s/\s+$//; # chomp
$hash{$line}{$file}++;
}
close $fh;
}

print Dumper \%hash;


Output (using customised input data):

Code
$VAR1 = { 
'401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14 mycustomline2' => {
'input2.txt' => 1
},
'401879077|7318645|01-JUL-2014|520|1954190|15.27|DAD|2I|1172|14' => {
'input.txt' => 1,
'input2.txt' => 1
},
'401879162|611030|01-JUL-2014|520|1985950|3.99|DAD|2I|1172|14' => {
'input.txt' => 1,
'input2.txt' => 1
},
'401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14' => {
'input.txt' => 1,
'input2.txt' => 1
},
'401879170|13859405|01-JUL-2014|520|1675310|2.99|DAD|2I|1172|14' => {
'input.txt' => 1,
'input2.txt' => 1
},
'401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14' => {
'input.txt' => 3
},
'401879125|611030|01-JUL-2014|520|1984030|1.06|DAD|2I|1172|14' => {
'input.txt' => 1,
'input2.txt' => 1
},
'401879339|6673455|01-JUL-2014|520|1967630|10.99|DAD|2I|1172|14' => {
'input.txt' => 1,
'input2.txt' => 1
},
'401879142|611030|01-JUL-2014|520|1983390|1.05|DAD|2I|1172|14' => {
'input.txt' => 1,
'input2.txt' => 1
},
'401879198|1773481|01-JUL-2014|520|1974670|8.82|DAD|2I|1172|14' => {
'input.txt' => 1,
'input2.txt' => 1
},
'401879133|8264305|01-JUL-2014|520|1966350|7.59|DAD|2I|1172|14' => {
'input.txt' => 1,
'input2.txt' => 1
},
'401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14 mycustomline1' => {
'input.txt' => 1
}
};


Regards,

Chris


(This post was edited by Zhris on Aug 28, 2014, 3:59 AM)


Tejas
User

Aug 28, 2014, 4:14 AM

Post #7 of 21 (3511 views)
Re: [Zhris] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

Sorry Chris
By Logging what i meant was

1.Matched Lines in a files
2. UnMatched Lines in a seperate file (If the values have mismach)
3. Missing Lines in seperate file :
If a line is avaialble once in first file and its available twice in second file (or vice versa ), then ideally its missing once and found once


Did u get it ?

Thanks
Tejas


Zhris
Enthusiast

Aug 28, 2014, 4:30 AM

Post #8 of 21 (3508 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

No problem, definitely a lot clearer now, but it would be considerably easier if you physically showed all of your expected output data, then I can confirm any remaining discrepancies between our understanding, especially under undescribed scenarios. In your previous post, you did exactly this by providing a "DESIRED OUTPUT" section.

Anyhow, please configure and test the code I provided above, it appears to parse your input files appropriately, ready for processing / output. Its then a simple case of comparing the counts (assume 0 if key / value pair is missing) and deciding how to output based on this comparison.

Regards,

Chris


(This post was edited by Zhris on Aug 28, 2014, 4:31 AM)


Tejas
User

Aug 28, 2014, 5:04 AM

Post #9 of 21 (3504 views)
Re: [Zhris] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

CTO_TRANSACTIONS_TEMP1

Quote
401879077|7318645|01-JUL-2014|520|1954190|155.27|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879133|8264305|01-JUL-2014|520|1966350|7.59|DAD|2I|1172|14
401879339|6673455|01-JUL-2014|520|1967630|10.99|DAD|2I|1172|14
401879142|611030|01-JUL-2014|520|1983390|1.05|DAD|2I|1172|14
401879125|611030|01-JUL-2014|520|1984030|1.06|DAD|2I|1172|14
401879198|1773481|01-JUL-2014|520|1974670|8.82|DAD|2I|1172|14
401879170|13859405|01-JUL-2014|520|1675310|2.99|DAD|2I|1172|14
401879162|611030|01-JUL-2014|520|1985950|3.99|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14

Txns_In_CLR1.txns

401879077|7318645|01-JUL-2014|520|1954190|15.27|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879133|8264305|01-JUL-2014|520|1966350|7.59|DAD|2I|1172|14
401879339|6673455|01-JUL-2014|520|1967630|10.99|DAD|2I|1172|14
401879142|611030|01-JUL-2014|520|1983390|1.05|DAD|2I|1172|14
401879125|611030|01-JUL-2014|520|1984030|1.06|DAD|2I|1172|14
401879198|1773481|01-JUL-2014|520|1974670|8.82|DAD|2I|1172|14
401879170|13859405|01-JUL-2014|520|1675310|2.99|DAD|2I|1172|14
401879162|611030|01-JUL-2014|520|1985950|3.99|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14


Matching_Output

Quote
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879133|8264305|01-JUL-2014|520|1966350|7.59|DAD|2I|1172|14
401879339|6673455|01-JUL-2014|520|1967630|10.99|DAD|2I|1172|14
401879142|611030|01-JUL-2014|520|1983390|1.05|DAD|2I|1172|14
401879125|611030|01-JUL-2014|520|1984030|1.06|DAD|2I|1172|14
401879198|1773481|01-JUL-2014|520|1974670|8.82|DAD|2I|1172|14
401879170|13859405|01-JUL-2014|520|1675310|2.99|DAD|2I|1172|14
401879162|611030|01-JUL-2014|520|1985950|3.99|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14

Missing Txns

Quote

401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14


UnaMatched Txns

401879077|7318645|01-JUL-2014|520|1954190|155.27|DAD|2I|1172|14 and
401879077|7318645|01-JUL-2014|520|1954190|15.27|DAD|2I|1172|14


Will Be Glad if u can help me out printing above output from the hash u ve generated.
Hope its much clearer :)

Thanks
Tejas


Zhris
Enthusiast

Aug 28, 2014, 5:46 AM

Post #10 of 21 (3502 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

How about the following hash processor, to be used in conjunction with the above code (not writing to output files yet).


Code
while ( my ( $line, $counts ) = each %hash ) 
{
my $count1 = $counts->{$files[0]} // 0;
my $count2 = $counts->{$files[1]} // 0;

if ( $count1 and $count2 )
{
print "MATCHING:\t$line\n";
print "MISSING:\t$line\n" x ( $count1 - $count2 );
}
else
{
print "UNMATCHING:\t$line\n";
}
}


Could you please test this in depth and let me know if any particular scenario is problematic. I'm particularly concerned with print do { "MISSING:\t$line\n" x ( $count1 - $count2 ) }; since it deliberately only works one way i.e. handles file 1 duplicates, but not file 2 duplicates.

Regards,

Chris


(This post was edited by Zhris on Aug 29, 2014, 12:46 AM)


Tejas
User

Aug 28, 2014, 10:13 AM

Post #11 of 21 (3484 views)
Re: [Zhris] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

Thanks Zhris , I will test the code and get back.

Thanks for your Inputs

I ll Probably set a flag, which interchages the file names when ever required, as the two way test is nt posssible in single shot.


Thanks
Tejas


Zhris
Enthusiast

Aug 28, 2014, 7:37 PM

Post #12 of 21 (3430 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

If you want to handle the "missing" lines both ways in one shot, then you could repeat the line by the highest count minus the lowest count:


Code
print do { "MISSING:\t$line\n" x ( $count1 > $count2 ? $count1 - $count2 : $count2 - $count1 ) };


Or perhaps you would prefer to write each way to a separate file:


Code
print do { "MISSING1:\t$line\n" x ( $count1 - $count2 ) }; 
print do { "MISSING2:\t$line\n" x ( $count2 - $count1 ) };


There is also the possibility that the right hand count should always be 1 too, therefore literally counting the number of extra lines without considering the opposite file.

If you get stuck let me know how you wish to handle this particular scenario.

Chris


(This post was edited by Zhris on Aug 28, 2014, 7:55 PM)


Tejas
User

Aug 29, 2014, 12:03 AM

Post #13 of 21 (3419 views)
Re: [Zhris] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

Hi Chris

Can you please explain the code linewise
as iam confused abt what it does,

Code
while ( my ( $line, $counts ) = each %hash )  
{
my $count1 = $counts->{$files[0]} // 0; //Waht does //0 mean ?
my $count2 = $counts->{$files[1]} // 0;

if ( $count1 and $count2 ) //wht is this if checking (True and True)
{
print "MATCHING:\t$line\n";
print do { "MISSING:\t$line\n" x ( $count1 - $count2 ) }; //Again , What does x specify, and what is "print do"
}
else
{
print "UNMATCHING:\t$line\n";
}
}

This is most advanced code i suppose :)



Thanks
Tejas


(This post was edited by Tejas on Aug 29, 2014, 12:09 AM)


Zhris
Enthusiast

Aug 29, 2014, 12:43 AM

Post #14 of 21 (3409 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

Hi,




Quote
Waht does //0 mean ?

It is a short form for:

Code
my $count1 = $counts->{$files[0]}; 
if ( not defined $count1 )
{
$count1 = 0;
}

When we read the files into a hash, if a line didn't exist in a particular file then the count would be undefined (non existent key / value pair), whereas it is better represented as 0. Technically it is not necessary to do this, removing this notation will have no effect in the codes current state.




Quote
wht is this if checking (True and True)

Thats right, it is a short form for:

Code
if ( $count1 >= 1 and $count2 >= 1 )

Any non 0 number is regarded as true. It tests that the line exists in both files atleast once.




Quote
What does x specify

It is a short form for:

Code
my $duplicates_count = $count1 - $count2; 
for ( 1 .. $duplicates_count )
{
print "MISSING:\t$line\n";
}

x is the repeat operator. It repeats the left hand side the number of times on the right hand side. This allows us to print every duplicate line.




Quote
and what is "print do"

The do block is totally unnecessary, you can remove it (i'll update the code above to reflect this). I have a habit of using do blocks to group expression(s) where it may not be clear that they are related. A do block returns the last evaluated expression.



Chris


(This post was edited by Zhris on Aug 29, 2014, 1:02 AM)


Tejas
User

Aug 29, 2014, 1:11 AM

Post #15 of 21 (3389 views)
Re: [Zhris] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

Thanks Chris

I dint know a bit of that .
I ve learnt something new.

Thanks
Tejas


Tejas
User

Aug 30, 2014, 12:46 AM

Post #16 of 21 (3272 views)
Re: [Zhris] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

WHai if i need the values froom both the files at a time

EX :


Quote
401879317|82255|01-JUL-2014|520|16590|10.44|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14



Quote
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401812|1771|01-JUL-2014|520|19657|4.25|DAD|2I|1172|14



OUTPUT

Quote

Unmatch:

401879112|1771361|01-JUL-2014|520|4.25|12.75|DAD|2I|1172|14
Total Amount in both the files for a txn has to be appended

Match :
If a line is matching twice, it has to be printed twice in matched file.

401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879317|6782255|01-JUL-2014|520|1976590|10.44|DAD|2I|1172|14
401879112|1771361|01-JUL-2014|520|1965710|4.25|DAD|2I|1172|14

Missing in FIle1 :
401812|1771|01-JUL-2014|520|19657|4.25|DAD|2I|1172|14

Missing IN FIle2:
401879317|82255|01-JUL-2014|520|16590|10.44|DAD|2I|1172|14


I tried to tweak the code ,but im unable to get the seperated values of the line.

Thanks
TEJAS


(This post was edited by Tejas on Aug 30, 2014, 12:47 AM)


Zhris
Enthusiast

Aug 30, 2014, 1:49 AM

Post #17 of 21 (3267 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

Hi,

I can still think of scenarios that we haven't covered yet, you have also switched unmatch / missing namespace, which is confusing. I think the best thing to do is to work from the following hash processor, which tries to conditionalise every possible scenario. It is then up to you to re-write the print statements, which repeat using the x repeat operator $freq_common and/or $freq_extra number of times i.e. print "$line\n" x $freq_common; where appropriate:


Code
while ( my ( $line, $counts ) = each %hash )  
{
my $count1 = $counts->{$files[0]} // 0;
my $count2 = $counts->{$files[1]} // 0;

if ( $count1 and $count2 )
{
if ( $count1 == $count2 )
{
# line exists in both files an equal number of times.
my $freq_common = $count1; #|| $count2;
my $freq_extra = 0;
print "A($freq_common,$freq_extra)\t$line\n";
}
elsif ( $count1 > $count2 )
{
# line exists in both files but occurs more frequently in file1
my $freq_common = $count2;
my $freq_extra = $count1 - $count2;
print "B($freq_common,$freq_extra)\t$line\n";
}
elsif ( $count1 < $count2 )
{
# line exists in both files but occurs more frequently in file2
my $freq_common = $count1;
my $freq_extra = $count2 - $count1;
print "C($freq_common,$freq_extra)\t$line\n";
}
}
elsif ( $count1 and !$count2 )
{
# line only exists in file1
my $freq_common = 0;
my $freq_extra = $count1;
print "D($freq_common,$freq_extra)\t$line\n";
}
elsif ( !$count1 and $count2 )
{
# line only exists in file2
my $freq_common = 0;
my $freq_extra = $count2;
print "E($freq_common,$freq_extra)\t$line\n";
}
elsif ( !$count1 and !$count2 )
{
# impossible!
}
}


Chris


(This post was edited by Zhris on Aug 30, 2014, 1:52 AM)


Tejas
User

Sep 2, 2014, 3:57 AM

Post #18 of 21 (3102 views)
Re: [Zhris] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

Hi Chris

Can you please comment on this and can you tell me whether this is good or ugly.
And can the code be shrinked


Quote
File1
File1
28045071,1,56,DAD,418756991,0,-9.02,01-AUG-14,01-AUG-14,1
28045281,1,19,DAD,12701012015,0,-261.02,01-AUG-14,01-AUG-14,1
28045991,1,19,DAD,379031901,0,-22.42,01-AUG-14,01-AUG-14,1
2213506106,1,24,DAD,1374249100,0,-20,01-AUG-14,01-AUG-14,1
2213506116,1,24,DAD,1374249100,0,-20,01-AUG-14,01-AUG-14,1
2264530076,1,24,DAD,1377063511,0,-350,01-AUG-14,01-AUG-14,1
2613542516,1,24,DAD,501029031,0,-30,01-AUG-14,01-AUG-14,1
2634699316,1,24,DAD,512242996,0,-100,01-AUG-14,01-AUG-14,1
2639141256,1,24,DAD,13496038905,0,-25,01-AUG-14,01-AUG-14,1
2641900466,1,24,DAD,56276190,0,-50,01-AUG-14,01-AUG-14,1
28053391,1,19,DAD,766709012,0,-70,01-AUG-14,01-AUG-14,1



Quote
28051341,1,56,DAD,199610116,0,-12.74,02-AUG-14,02-AUG-14,1
28051961,1,19,DAD,6735124615,0,-36.45,02-AUG-14,02-AUG-14,1
28052061,1,19,DAD,394104487,0,-48.61,02-AUG-14,02-AUG-14,1
28053391,1,19,DAD,766709012,0,-60,02-AUG-14,02-AUG-14,1
2399932016,1,24,DAD,567508320,0,-50,02-AUG-14,02-AUG-14,1
2451060666,1,24,DAD,499140250,0,-50,02-AUG-14,02-AUG-14,1
2495205736,1,24,DAD,774256411,0,-20,02-AUG-14,02-AUG-14,1
2604153876,1,24,DAD,7378719,0,-50,02-AUG-14,02-AUG-14,1
2638779256,1,24,DAD,240129917,0,-50,02-AUG-14,02-AUG-14,1
2646215356,1,24,DAD,1036846291,0,-40,02-AUG-14,02-AUG-14,1


Quote
OUTPUT
OUTPUT
28045071,1,56,DAD,418756991,0,-9.02,01-AUG-14,01-AUG-14,1
28045281,1,19,DAD,12701012015,0,-261.02,01-AUG-14,01-AUG-14,1
28045991,1,19,DAD,379031901,0,-22.42,01-AUG-14,01-AUG-14,1
2213506106,1,24,DAD,1374249100,0,-20,01-AUG-14,01-AUG-14,1
2213506116,1,24,DAD,1374249100,0,-20,01-AUG-14,01-AUG-14,1
2264530076,1,24,DAD,1377063511,0,-350,01-AUG-14,01-AUG-14,1
2613542516,1,24,DAD,501029031,0,-30,01-AUG-14,01-AUG-14,1
2634699316,1,24,DAD,512242996,0,-100,01-AUG-14,01-AUG-14,1
2639141256,1,24,DAD,13496038905,0,-25,01-AUG-14,01-AUG-14,1
2641900466,1,24,DAD,56276190,0,-50,01-AUG-14,01-AUG-14,1
28051341,1,56,DAD,199610116,0,-12.74,02-AUG-14,02-AUG-14,1
28051961,1,19,DAD,6735124615,0,-36.45,02-AUG-14,02-AUG-14,1
28052061,1,19,DAD,394104487,0,-48.61,02-AUG-14,02-AUG-14,1
28053391,1,19,DAD,766709012,0,-60,02-AUG-14,02-AUG-14,1 This Txn is repeated and the latest has to be considered, Second File being the latest.
2399932016,1,24,DAD,567508320,0,-50,02-AUG-14,02-AUG-14,1
2451060666,1,24,DAD,499140250,0,-50,02-AUG-14,02-AUG-14,1
2495205736,1,24,DAD,774256411,0,-20,02-AUG-14,02-AUG-14,1
2604153876,1,24,DAD,7378719,0,-50,02-AUG-14,02-AUG-14,1
2638779256,1,24,DAD,240129917,0,-50,02-AUG-14,02-AUG-14,1
2646215356,1,24,DAD,1036846291,0,-40,02-AUG-14,02-AUG-14,1


We can see that
28053391,1,19,DAD,766709012,0,-70,01-AUG-14,01-AUG-14,1
is repeated in both the files, but the latest should be considered and should be printed.
So, In the output the second file's data is printed


Output has All First Files Txns and All Second Files Txns and if the Txn Repeats (Key is first column) in second file,
Second file's data has to be considered.

Code
#! /usr/bin/perl 

my $pwd = `pwd`;
chomp($pwd);
my $clr_txns= "$pwd/File1.txt";
my $temp_file = "$pwd/File2.txt";
my $final_output= "$pwd/Final_List.txt";
open (FIRST,"< $clr_txns")or die "could not open $clr_txns $!";
open (SECOND,"< $temp_file")or die "could not open $cto_txns $!";
open (MATCH,"> $final_output")or die "could not open $final_output$!";

my %hash = ();
my %hash1 = ();
while (my $line = <FIRST>) {
my @elements = split ',', $line;
my $key = $elements[0];
print "$key\n";
$hash{$key} = 1;
$hash2{$key} = $line;
}
#open SECOND, "< $secondFile" or die "could not open second file...\n";
while (my $line = <SECOND>) {
my @elements = split ',', $line;
my $key = $elements[0]; # Perl arrays are zero-indexed
if ($hash{$key}) {
#print "($hash{$key} \n";
print MATCH "$line";
$hash{$key} = 0;
}
else {
print MATCH "$line" ; #Also Print unmatched, as we need all the txns from both the files
}
}
while( my( $key, $value ) = each %hash2 ){
if($hash{$key} != 0) {
print MATCH "$value"; # Print the values of other files, and eliminate the matched ones
}


}

close (FIRST);
close (SECOND);


Thanks
Tejas


Laurent_R
Veteran / Moderator

Sep 2, 2014, 9:58 AM

Post #19 of 21 (3094 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

I do not think that you need two hashes, one should be sufficient.

You're declaring %hash1 and then using $hash2, which shows that you are not using strictures and warnings, although I am sure you've been told to do so several times on this forum.

I am also almost sure you've also been told to use lexical filehandles and the 3-argument syntax for opening a file.

Try to use more consistant indentation, it will help you understanding the structure of your program.


Code
     my @elements = split ',', $line;  
my $key = $elements[0];


is better written with a regex:


Code
     my @elements = split /,/, $line;  
my $key = $elements[0];


and can also be shortened as follows:

Code
my $key = (split /,/, $line)[0];



Tejas
User

Sep 2, 2014, 11:34 AM

Post #20 of 21 (3088 views)
Re: [Laurent_R] How to Print the Value of a key in multilevel hash [In reply to] Can't Post


Quote
You're declaring %hash1 and then using $hash2, which shows that you are not using strictures and warnings, although I am sure you've been told to do so several times on this forum.


Laurent, Can u please explain me , i thought its fine.
Please explain me the problematic statements i hav eused.
Did u mean i shudnt be using these names (%hash1 ,hash2)

i understood ur second comment

Quote
open my $in, '<', $filname;


Thanks
Tejas


(This post was edited by Tejas on Sep 2, 2014, 11:37 AM)


Laurent_R
Veteran / Moderator

Sep 2, 2014, 11:31 PM

Post #21 of 21 (3063 views)
Re: [Tejas] How to Print the Value of a key in multilevel hash [In reply to] Can't Post

I am just saying that you are declaring %hash1:

Code
my %hash1 = ();

and never use %hash1. On the other hand you are using %hash2 in the each statement near the end, but have never declared %hash2.

This is a coding error which the compiler would warn you about if you had:

Code
use strict; 
use warnings;

near the beginning of your code. And you should always have that, it will save you a lot of time.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives