# always use strict and warnings - debugging for free! use strict; use warnings; my %current = ('C:\1\x\3\4' => 'created', 'C:\1\x\3' => 'created', 'C:\1\x' => 'created' 'C:\1\2\3\4' => 'deleted', 'C:\1\2\3' => 'deleted', 'C:\1\2' => 'deleted' ); my %unique; node: foreach my $node (sort keys %current) { #look for parent directories in %unique #skip this one if we find a match my @aNames = split(/\\/, $node); my $k=''; for my $i (0..$#aNames) { $k .= '\\' if $i; $k .= $aNames[$i]; next node if exists $unique{$k}; } #no match, so this is the actual directory that moved $unique{$k} = $current{$k}; } use Data::Dumper qw(Dumper); print(Dumper(\%unique)); #outputs #$VAR1 = { # 'C:\\1\\x' => 'created' # 'C:\\1\\2' => 'deleted' # };