use strict; use warnings; use Data::Dumper; my %results; #pick a better name for this!! my $eof_seen = 0; while (!$eof_seen) { my %record = get_record(); my ($solvent) = grep {/^solvent/ and $record{$_}==0}keys %record; foreach my $F (grep {/^F/}keys %record) { $results{$solvent."_".$F}= $record{$F}; } $eof_seen=1 if (eof(DATA)); } print Dumper \%results; sub get_record #blank line separated records { my %record; my $line; while (defined ($line = ) and $line !~ /^\s*$/) { my ($key, $value) = split ' ',$line; $record{$key} = $value; } return %record; } =Prints $VAR1 = { 'solvent1_F101' => '3.2', 'solvent1_F001' => '1.2', 'solvent2_F101' => '7.2', 'solvent2_F001' => '2.2' }; =cut __DATA__ F001 1.2 F101 3.2 solvent1 0 solvent2 3 F001 2.2 F101 7.2 solvent1 5 solvent2 0