use strict; use warnings; use Data::Dumper; my $hash; while (){ my ($left,$val) = split /=/,$_ or next; my ($first,@levels) = split /\./,$left; my $str="\$hash->{$first}"; for my $last_level(@levels){ $str .= "{$last_level}" } eval "$str=$val"; } print Dumper \$hash; __DATA__ a.b='xyz' a.c='abc' d='def' a.e='ghi'