use Data::Dump 'pp'; # a "better" Data::Dumper my %obs; while ( ) { chomp; my ( $obs_num, $det, $x, $y ) = split; push @{ $obs{$obs_num}{$det} }, { x => $x, y => $y }; } #$obs{$obs_num}{$det}[$reading]{x} pp \%obs; __DATA__ 21 DET-2 896.657564735788 678.83860967799 21 DET-3 32.0939023018969 621.656550474314 21 DET-3 42.0741462550974 834.842294892622 21 DET-3 218.814294809857 450.606540154849 21 DET-3 228.88830316475 625.939190221948 21 DET-3 630.472705847461 220.839350101088 21 DET-5 152.988115061449 156.31861287082 88 DET-0 114.871177986263 212.959076023136 88 DET-0 219.421725079137 710.314439572696 88 DET-0 257.837516726887 594.376577764894 88 DET-1 119.630462310966 260.433234269099 #### { 21 => { "DET-2" => [{ "x" => "896.657564735788", "y" => "678.83860967799" }], "DET-3" => [ { "x" => "32.0939023018969", "y" => "621.656550474314" }, { "x" => "42.0741462550974", "y" => "834.842294892622" }, { "x" => "218.814294809857", "y" => "450.606540154849" }, { "x" => "228.88830316475", "y" => "625.939190221948" }, { "x" => "630.472705847461", "y" => "220.839350101088" }, ], "DET-5" => [{ "x" => "152.988115061449", "y" => "156.31861287082" }], }, 88 => { "DET-0" => [ { "x" => "114.871177986263", "y" => "212.959076023136" }, { "x" => "219.421725079137", "y" => "710.314439572696" }, { "x" => "257.837516726887", "y" => "594.376577764894" }, ], "DET-1" => [{ "x" => "119.630462310966", "y" => "260.433234269099" }], }, }