Goku Goku - 1 year ago 111
Perl Question

Perl hash formatting

I have a log file like below

ID: COM-1234
Program: Swimming
Name: John Doe
Description: Joined on July 1st
------------------------------ID: COM-2345
Program: Swimming
Name: Brock sen
Description: Joined on July 1st
------------------------------ID: COM-9876
Program: Swimming
Name: johny boy
Description: Joined on July 1st
------------------------------ID: COM-9090
Program: Running
Name: justin kim
Description: Good Record

and I want to group it based on the Program (Swimming , Running etc) and want a display like,

PROGRAM: Swimming

PROGRAM: Running

I'm very new to Perl and I wrote the below piece (incomplete).

use Data::Dumper;

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

my %hash = @new;
print Dumper(\%hash);

I have read from perl tutorials that hash key-value pairs will take unique keys with multiple values but not sure how to make use of it.

I'm able to read a file and store in to hash, unsure how to process to the aforementioned format.Any help is really appreciated.Thanks.

Answer Source

I always prefer to write programs like this so they read from STDIN as that makes them more flexible.

I'd do it like this:


use strict;
use warnings;
use 5.010;

# Read one "chunk" of data at a time
local $/ = '------------------------------';

# A hash to store our results.
my %program;

# While there's data on STDIN...
while (<>) {
  # Remove the end of record marker
  # Skip any empty records
  # (i.e. ones with no printable characters)
  next unless /\S/;

  # Extract the information that we want with a regex
  my ($id, $program) = /ID: (.+?)\n.*Program: (.+?)\n/s;
  # Build a hash of arrays containing our data
  push @{$program{$program}}, $id;

# Now we have all the data we need, so let's display it.

# Keys in %program are the program names
foreach my $p (keys %program) {
  say "PROGRAM: $p\n==>ID";
  # $program{$p} is a reference to an array of IDs
  say "\t$_" for @{$program{$p}};
  say '';

Assuming this is in a program called programs.pl and the input data is in programs.txt, then you'd run it like this:

C:/> programs.pl < programs.txt