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