use File::Basename qw( basename ); sub visit { my ($dir, $level) = @_; $level ||= 0; my $group_indent = ' ' x (2*$level); ++$level; my $child_indent = ' ' x (2*$level); printf($group_indent."Group: %s {\n", $level ? basename($dir) : $dir); my @file_names = do { opendir(my $dh, $dir); grep !/^\.\.?\z/, readdir($dh) }; for my $fn (@file_names) { my $qfn = "$dir/$fn"; if (-d $qfn) { visit($qfn, $level); } else { print($child_indent."File: $fn ($qfn)\n"); } } print($group_indent."}\n"); } visit('/proj/newdata');