http://www.perlmonks.org?node_id=531681

uksza has asked for the wisdom of the Perl Monks concerning the following question:

Wise Monks,

It's hard to say what I need, so I use some examples:
I have directiories:
/root +dir1 +1a +1b +dir2 +2a +2b +2c
without exceptions my directiories list shoud look:
/root
with exception on /root/dir2/2b:
/root/dir1 /root/dir2/2a /root/dir2/3a
So, I use some code from runrig on How do I recurse all *but* a few directories? and I've made this:
use File::Find; my @abs_dirs = qw ( /usr/local/share/locale ); my %abs_dirs; @abs_dirs{@abs_dirs} = (); my @OK_dir; my %all; find( sub { $File::Find::prune = 1, return if -d and ( exists $abs_dirs{$File::Find::name} ); my $dir = $File::Find::name; return if -f $dir; if ( ( grep { $_ =~ m/$dir/ } @abs_dirs ) and ( !exists $all{$ +dir} ) ) { $all{$dir}; } else { push @OK_dir, $dir; $File::Find::prune = 1; return; } }, "/usr/local/" );
It works, but I wonder if is any better way to do it? I dont't think about usless $all{$dir}, but about totally difrent way.
Thanks for your help and time,

greetz, Uksza

Yes, smart people know that fat arrow autoquotes the left argument. But why should you require your code to be maintained by smart people?
Randal L. Schwartz, Perl hacker

2006-02-21 Retitled by planetscape, as per Monastery guidelines
Original title: 'Directiories without recursion and exceptions'

Replies are listed 'Best First'.
Re: Directories without recursion and exceptions
by davidrw (Prior) on Feb 21, 2006 at 14:03 UTC
    not sure i understand your exceptions requirements, but File::Find::Rule might make things easier ..
    use File::Find::Rule; my @search = qw( /usr/local/ ); my @abs_dirs = qw ( /usr/local/share/locale ); my %abs_dirs; @abs_dirs{@abs_dirs} = (); my @dirs = grep { ! exists $abs_dirs{$_} } File::Find::Rule->directory +()->in( @search );
      Not sure if FFR can do this directly, but my File::Finder can also do:
      use File::Finder; my @search = qw( /usr/local/ ); my @abs_dirs = qw ( /usr/local/share/locale ); my %abs_dirs; @abs_dirs{@abs_dirs} = (); my @dirs = File::Finder->type('d')->eval(sub { not exists $abs_dirs{$F +ile::Find::name}})->in(@search);

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        All in one w/FFR:
        my @files = File::Find::Rule->directory()->exec( sub { ! exists $abs +_dirs{$_[2]} } )->in( @search );
        I was actually looking at both FFR and File::Finder for this task .. codes comes out pretty similar for both :)
      Hi,
      Thanx a lot for your reply!
      Some more about my exceptions:
      I've got program (scaner) whitch can scan directories with recursion but don't have --except parametr. So, if I want scan /home (except /home/user3) I must write:
      ./scaner /home/user1 /home/user2 /home/user4 /home/user5
      But what if I have 100 users and 12 exceptions? And what if I want to scan / with 12 exceptions in /home 5 in /usr and some more?
      I use my script and make list all directiories without unnecessary subdirectories (/home/user1/mail etc).
      And I just wonder if is any smarter way to do it.

      greetz, Uksza

      Yes, smart people know that fat arrow autoquotes the left argument. But why should you require your code to be maintained by smart people?
      Randal L. Schwartz, Perl hacker