Goku Goku - 3 months ago 10
Perl Question

Perl process and store unique values in array

Below is the log file content and I'm reading the log file and grouping it based on the string - JIRA.

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 requirement is , iterate thru every unique JIRA value - COM-1234 , COM-6789, etc and store the following or immediate details in to individual array like

(for COM-1234)

@prog = Development;
@Reviewer = John Wick;
@Description = Genral fix;
@rev = r345676;


(for COM-6789)

@prog = Testing;
@Reviewer = Balise Mat;
@Description = Audited;
@rev = r876391;


If the JIRA value is identical , say COM-1234 repeated 2 times and COM-6789 for 3 times , still push only the following or immediate details to the respective arrays. (i.e. values of the keys 'Program','Reviewer' ....)

(COM-1234)

@prog = Development;
@Reviewer = None;
@Description = Updating Received ;
@rev = r909276;


I'm very new to Perl and I can manage to reach only for the unique values and not sure how to push the following values to individual arrays.
Any inputs will be really helpful. Thanks.

My incomplete code:

#!/usr/bin/perl
use warnings;
use Data::Dumper;

$/ = "%%%%";
open (AFILE, ""<", ""D:\\mine\\out.txt");
while (<AFILE>)
{
@temp = split(/-{20,}/, $_);
}
close (AFILE);

my %jiraHash;
for ($i=0; $i<=@temp; $i++) {
if (($temp[$i] =~ /(((JIRA|SVN)\s{0,1}:(\s{0,2}[A-Za-z0-9-\s]{4,9}),
{0,1}\s{0,2}){1,5})\nProgram\s{0,1}:\s{0,2}Development/) ||
($temp[$i] =~ /(((JIRA|SVN):(\s{0,2}[A-Za-z0-9-\s]{4,9}),
{0,1}\s{0,2}){1,5})\nProgram\:\s{0,2}Testing/)) {

$jiraId = $2;
$jiraId =~ s/JIRA\s*\://;
$temp[$i] =~ s/\w{3,}\s?:\s?//g;
#print "==>$jiraId\n";
$jiraHash{$jiraId} = $temp[$i];

} else {
#print "NOT\n";
}
}
print Dumper(%jiraHash);


I'm planning display as HTML report in below format

Program: Development
FOR ID: COM-1234

Revision Reviewer Comment
r345676 John Wick Genral fix

Revision Reviewer Comment
r909276 None Updating Received

Program: Testing
FOR ID: COM-6789

Revision Reviewer Comment
r876391 Balise Mat Audited

Revision Reviewer Comment
r698392 Chan Joe SO hwat

Revision Reviewer Comment
r327896 Chan Joe Paid the Due

Answer

It sounds like this data should be in a database.

But it is relatively simple to parse it into a data structure. Here, I've gone for a hash where the key is the Jira identifier and the value is a reference to an array that contains hash references. Each of the referenced hashes contains the details from one of the records.

#!/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{JIRA}}}, \%rec;
}

say Dumper \%jira;

When you run it on your given data, you get this output:

$VAR1 = {
          'COM-6789' => [
                          {
                            'Program' => 'Testing',
                            'JIRA' => 'COM-6789',
                            'rev' => 'r876391',
                            'Reviewer' => 'Balise Mat',
                            'Description' => 'Audited'
                          },
                          {
                            'Program' => 'Testing',
                            'JIRA' => 'COM-6789',
                            'rev' => 'r698392',
                            'Reviewer' => 'Chan Joe',
                            'Description' => 'SO hwat '
                          },
                          {
                            'Program' => 'Testing',
                            'JIRA' => 'COM-6789',
                            'rev' => 'r327896',
                            'Reviewer' => 'Chan Joe',
                            'Description' => 'Paid the Due'
                          }
                        ],
          'COM-1234' => [
                          {
                            'Program' => 'Development',
                            'JIRA' => 'COM-1234',
                            'rev' => 'r345676',
                            'Reviewer' => 'John Wick ',
                            'Description' => 'Genral fix'
                          },
                          {
                            'Program' => 'Development',
                            'JIRA' => 'COM-1234',
                            'rev' => 'r909276',
                            'Reviewer' => 'None',
                            'Description' => 'Updating Received '
                          }
                        ]
        };

From there, it's relatively simple to get a display of the data:

foreach my $j (keys %jira) {
  say "JIRA: $j";
  foreach (@{$jira{$j}}) {
    say "Program: $_->{Program}";
    say "Revision: $_->{rev}";
    # etc...
  }
}