use strict; use warnings; my %hash = (); my ($time, $conference, $type,$comment); while() { # adapt parsing values to your need here if (/conference=(.*)/){ $time = $1; } if (/conference=(.*)/){ $conference = $1; } if (/type=(.*)/){ $type = $1; } if (/comment=(.*)/){ $comment = $1; } if (/lastline of record/){ $hash{$time,$conference}{time} = $time; $hash{$time,$conference}{conference} = $conference; # info is already in the key, for easy parsing in the for loop, store conference twice. $hash{$time,$conference}{type} = $type; $hash{$time,$conference}{comment} = $comment; } } for my $timeconference (sort keys %hash) { printf "time %s, conference %s, type %s, comment %s\n", @{hash}{qw(time conference type comment)}; }