Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^2: Hash of Hash of Arrays

by voltas (Novice)
on Aug 25, 2016 at 10:06 UTC ( #1170400=note: print w/replies, xml ) Need Help??


in reply to Re: Hash of Hash of Arrays
in thread Hash of Hash of Arrays

Hi @duyet, Really appreciate your help here. Now shared the entire details. My input log file is below:
JIRA: COM-1234 Program:Development Reviewer:John Wick Description:Genral fix rev:r345676 ------------------------------------------ JIRA:COM-1234 Program:Development Reviewer:None Description:Updating Received rev:r909276 ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Balise Mat Description:Audited rev:r876391 ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Chan Joe Description:SO hwat rev:r698392 ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Chan Joe Description:Paid the Due rev:r327896 ------------------------------------------
My incomplete code is below.
#!/usr/bin/perl use strict; use warnings; use 5.010; use Data::Dumper; my @records = do { local $/ = '------------------------------'; <>; }; chomp @records; my %jira; foreach (@records) { next unless /\S/; my %rec = /^(\w+):\s*(.+?)$/mg; push @{$jira{$rec{Program}}{$rec{JIRA}}}, \%rec; } #say Dumper \%jira; foreach $prg (keys %jira) { print "=========================================================== +=\n"; print " PROGRAM : prg + \n"; print "=========================================================== +=\n"; foreach $jira (keys %{$jira{$prg}}) { print "******************\n"; print "JIRA ID : $jira\n"; print "******************\n"; @myarr = @{$jira{$prg}{$jira}}; foreach $val (@myarr) { for $i ( 0 .. $#myarr ) { print "NO:$i\n"; foreach $key (keys %{$myarr[$i]}) { #print "KEY: $key\n"; print " ======> $val[$i]{revision}\n"; } } } } }
What I'm trying to accomplish is to read the log file and print the output in the below format.
================================== Program: Development =================================== ***************** JIRA ID: COM 1234 ***************** rev => r345676 Reviewer => John Wick Description => Genral fix rev => r909276 Description => Updating Received Reviewer => None ================================== Program: Testing =================================== ***************** JIRA ID: COM 6789 ***************** rev => r876391 Description => Audited Reviewer => Balise Mat rev => r698392 Reviewer => Chan Joe Description => SO hwat rev => r327896 Reviewer' => Chan Joe Description' => Paid the Due
I'm able to print the unique Program & JIRA ID but the revision, Reviewer and Description values are getting displayed multiple times for every single JIRA ID. Would you really appreciate any inputs. Thanks in advance.

Replies are listed 'Best First'.
Re^3: Hash of Hash of Arrays
by duyet (Friar) on Aug 26, 2016 at 10:37 UTC
    Below is how i did it. The data is saved in a separate file, and read line by line. There are other ways to read file, eg. File::Slurp or File::Map.

    It could have been done in 1 while loop, but i prefer 2 steps: 1st process the data, 2nd output the data. Then the code can be put in short subroutines, which i can easily create tests for them.

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; $Data::Dumper::Sortkeys = 1; $Data::Dumper::Terse = 1; my $file = 'perlmonk_1170305_02_data.txt'; open FH, $file or die "Couldn't open file: [$!]\n"; my $data = {}; my $hash = {}; while ( <FH> ) { my $line = $_; chomp $line; if ( $line =~ m/(-){2,}/ ) { # save all stored data if we see dashes line my $program = $hash->{Program} || ''; my $jira = $hash->{JIRA} || ''; if ( $program && $jira ) { push @{ $data->{ $program }{ $jira }}, $hash; $hash = {}; } } else { # store data in a temp hash my ( $key, $value ) = split /:\s*/, $line; $hash->{ $key } = $value; } } #print 'data = ' . Dumper( $data ); foreach my $prg ( sort keys %{ $data } ) { print "=========================================================== +=\n"; print " PROGRAM : $prg + \n"; print "=========================================================== +=\n"; foreach my $jira ( sort keys %{ $data->{ $prg }}) { print "******************\n"; print "JIRA ID : $jira\n"; print "******************\n"; foreach my $hash ( @{ $data->{ $prg }{ $jira }} ) { foreach my $key ( keys %{ $hash }) { # print the data except Program and JIRA next if $key =~ m/(Program|JIRA)/; print " $key => $hash->{ $key }\n"; } print "\n"; } } }
    Output:
    ============================================================ PROGRAM : Development ============================================================ ****************** JIRA ID : COM-1234 ****************** rev => r345676 Reviewer => John Wick Description => Genral fix rev => r909276 Reviewer => None Description => Updating Received ============================================================ PROGRAM : Testing ============================================================ ****************** JIRA ID : COM-6789 ****************** rev => r876391 Reviewer => Balise Mat Description => Audited rev => r698392 Reviewer => Chan Joe Description => SO hwat rev => r327896 Reviewer => Chan Joe Description => Paid the Due
      Thanks a ton duyet.. You are a life saver :) One final question pls. The log file has been updated with a new entry called Files, like below for example
      JIRA: COM-6789 Program:Testing Reviewer:Chan Joe Description:SO hwat rev:r698392 Files: dev/src/com/user/st/recall/api/API.java ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Chan Joe Description:Paid the Due rev:r327896 Files:base/dev/src/com/myorg/ng/order/util/Util.jsp;base/dev/src/com/m +yorg/ng/sterling/sth/api/Update.jsp base/dev/src/com/myorg/ng/order/basedesign/util/HDrals.jsp base/dev/src/com/myorg/ujio/update/test.jsp
      Since 'Files' may have multiple file entries separated by a newline like above, I'm facing the below message
      Files => base/dev/src/com/myorg/ng/order/util/Util.jsp;base/dev/src/ +com/myorg/ng/sterling/sth/api/Update.jsp Description => My design initiative . Use of uninitialized value in concatenation (.) or string at monk.pl l +ine 62, <FH> line 55. => base/dev/src/com/myorg/ng/order/basedesign/util/HDrals.jsp
      Kindly can you enlighten me how to handle the same and display the File entries one after anothe ?Thanks again.
        The code in the else block within the while loop should be changed:
        # store data in a temp hash if ( $line =~ m/:/ ) { my ( $key, $value ) = split /:\s*/, $line; $hash->{ $key } = $value; } elsif ( $line =~ m#/# && exists $hash->{Files} ) { $hash->{Files} .= ";$line"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1170400]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2020-04-04 00:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    The most amusing oxymoron is:
















    Results (32 votes). Check out past polls.

    Notices?