use strict; use warnings; my @d; # the data structure we're building. my @p; # current (actually previous) vector while () { chomp; my $r = \@d; my @vc = my @v = split m# / #; my @pc = @p; # bashable copy while ( @vc and @pc and $vc[0] eq $pc[0] ) { shift @vc; shift @pc; $r = $r->[-1]{'children'}; } while ( @vc ) { push @$r, { name => shift @vc }; $r = ( @vc and $r->[-1]{'children'} = [] ); } @p = @v; } use Data::Dumper; print Dumper \@d; __DATA__ one foo / bar foo / baz foo / qux / two foo / qux / three foo / qux / four five