#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $path_to_file = 'test.txt'; open my $fh, '<', $path_to_file or die "Could not open " . $path_to_file . " $!\n"; chomp(my @lines = <$fh>); close $fh or die "Could not close " . $path_to_file . " $!\n"; # Remove empty lines if this is desired? @lines = grep /\S/, @lines; my %HoA; foreach my $line (@lines) { my ($match, $remaining) = split(/\|\|\|/, $line); push (@{$HoA{$match}}, $remaining); } print Dumper \%HoA; my @updated_lines; foreach my $key (keys %HoA) { my $concat_str; foreach my $i ( 0 .. $#{ $HoA{$key} } ) { if ($i == 0){ $concat_str .= $HoA{$key}[$i] . "; "; } $concat_str .= $HoA{$key}[$i] . " "; } # Trim white space on right $concat_str =~ s/\s+$//; push @updated_lines, $key.$concat_str.'|||'; } print Dumper \@updated_lines; __END__ $ perl test.pl $VAR1 = { '21997' => [ '70049,,20170428154818,20170527235959', '70070,,20170428154739,20170527235959' ], '21998' => [ '70049,,20170428154818,20170527235959', '70070,,20170428154739,20170527235959', '70071,,20170428154739,20170527235959' ] }; $VAR1 = [ '2199770049,,20170428154818,20170527235959; 70049,,20170428154818,20170527235959 70070,,20170428154739,20170527235959|||', '2199870049,,20170428154818,20170527235959; 70049,,20170428154818,20170527235959 70070,,20170428154739,20170527235959 70071,,20170428154739,20170527235959|||' ];