my %dict; # A reverse index on %dict by id. while (my $line = <$fh>) { my ( $id, $parent, $term ) = split ' ', $line, 3; # Fixed from -3 per sauoq $dict{$id}{'id'} = $id; $dict{$id}{'parent'} = $parent; push @{$dict{$parent}{'children'}}, $dict{$id}; } use Data::Dumper; print Dumper( \ %dict );