use strict; use warnings; use Data::Dumper 'Dumper'; my %tree; while () { chomp; next unless ( /^\s*(\d+)\s*=>\s*(.*)/ ); my ( $key, $val ) = ( $1, $2 ); if ( $val eq '' ) { # leaf node $tree{$key} = {} unless exists( $tree{$key} ); # assign an empty hash ref } else { for my $node ( split /, +/, $val ) { if ( ! exists( $tree{$node} )) { $tree{$node} = {}; } $tree{$key}{$node} = \$tree{$node}; push @{$tree{$node}{parent}}, $key; # keep track of node parents } } } # all done: for ( sort keys %tree ) { print "======\n$_:\n", Dumper( $tree{$_} ) unless exists( $tree{$_}{parent} ); } # append your data below... __DATA__