use Data::Diver qw( DiveRef ); my $data; while () { chomp; my @keys = split /:/; my $val = pop(@keys); my $ref = DiveRef( $data, map \$_, @keys ); push @$ref, $val; }