use strict; use warnings; my %Entry; $Entry{-1} = ''; my @list; my $id; while(){ chomp; last if /OUTPUT/; my $entry = $1 if /\b(\w+)$/; my $level = () = $_ =~ m[\-]g; my $item; $Entry{$level} = $entry; #Remember the last entry $item->{id} = ++$id; $item->{name} = $entry; $item->{parent} = $Entry{$level-1}; $item->{level} = $level; push @list,$item; } foreach my $item (@list){ print join "|", map { $item->{$_} } qw(id level name parent); print "\n"; } __DATA__ foo ->bar -->troz ->narf __OUTPUT__ 1|0|foo| 2|1|bar|foo 3|2|troz|bar 4|1|narf|foo