use warnings; use strict; use Data::Dumper; my (%result, $subhash); while () { if (/^Data_Value/ ... /^Data_raw/) { my @value = split; my $value = $value[0] = ''; $value = "@value"; if (/^Data_Value/) { $subhash = $value; $result{$subhash} = {}; } $result{$subhash}->{Data_Group} = $value if /^Data_Group/; $result{$subhash}->{Data_raw} = $. if /^Data_raw/; } } print Dumper \%result; __DATA__ Data_Value -999 Data_Group Clock453 Data_raw -from point_q/point2 \ -of point_a/abc/Q/D \ . . -to endpoint/abc/CK Data_Value -123 Data_Group Clock453 Data_raw -from point_q/point2 \ -of point_a/abc/Q/D \ . . -to endpoint/abc/CK Data_Value -666 Data_Group Clock453 Data_raw -from point_q/point2 \ -of point_a/abc/Q/D \ . . -to endpoint/abc/CK #### user@unforgiven:~$ perl tst.pl $VAR1 = { ' -123' => { 'Data_Group' => ' Clock453', 'Data_raw' => '10' }, ' -999' => { 'Data_Group' => ' Clock453', 'Data_raw' => '3' }, ' -666' => { 'Data_Group' => ' Clock453', 'Data_raw' => '17' } };