#!/usr/bin/env perl use strict; use warnings; use autodie; use constant BASE_DIR => '/home/ken/tmp/pm_11143050'; use constant { LEN_BASE_DIR => length BASE_DIR, FS_DIR => BASE_DIR . '/fs', }; use Cwd 'abs_path'; use Data::Dump; my %fs_map; walk_fs(FS_DIR, \%fs_map); dd \%fs_map; sub walk_fs { my ($path, $fs_map) = @_; opendir(my $dh, $path); while (readdir $dh) { next if /^\.{1,2}$/; my $entry = "$path/$_"; my $fs_path = fs_path($entry); if (-f $entry) { $fs_map->{$fs_path} = [file => []]; } elsif (-l $entry) { $fs_map->{$fs_path} = [link => [canon_path($entry)]]; } elsif (-d $entry) { if (exists $fs_map->{fs_path($path)}) { push @{$fs_map->{fs_path($path)}[1]}, canon_path($entry); } $fs_map->{$fs_path} = [dir => []]; walk_fs($entry, $fs_map); } else { warn "IGNORED '$entry': not a plain file, link or directory.\n"; } } closedir $dh; return; } sub fs_path { return substr $_[0], LEN_BASE_DIR; } sub canon_path { return substr abs_path($_[0]), LEN_BASE_DIR; }