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

I am having a file, list.name which has following directory names t1,t2,t3 and so on. This file is present in directory dir1. Also in directory dir1, i am having directories like t1,t11,t12,t2,t21,t22 and so on. I want to delete all the directories which are not in file list.name
  • Comment on delete all directories which are not in list

Replies are listed 'Best First'.
Re: delete all directories which are not in list
by saskaqueer (Friar) on Feb 10, 2005 at 07:00 UTC

    Here's one way of doing it:

    #!/usr/bin/perl -w use strict; chdir('dir1'); open(my $fh, '<', 'list.name') or die("open() failed: $!"); my %all = map { $_ => undef } grep { -d } glob("*"); delete($all{$_}) for ( map { chomp; split(/,/, $_) } <$fh> ); system('rm', '-ir', $_) for (keys(%all)); __END__ format of dir1/list.name: dir1,dir2,dir3,dir4,etc dir10,dir11, dir12,dir_x
      in list.name file the entries are not seperated by ,(comma) they are placed in line by line manner such as there is one entry in one line and each entry corrospond to a directory name which is actually present in directort dir1

        Well then, maybe next time you ask a question, you will specify more details. How was I supposed to know you had one entry per line? I just assumed comma-separated because that's the closest assumption I could make out of the original posting. In any case, the code I provided will work for a one-item-per-line file anyway. But here's a refactored version of the whole thing:

        #!/usr/bin/perl -w use strict; chdir('dir1'); open(my $fh, '<', 'list.name') or die("open() failed: $!"); my %all = map { $_ => undef } grep { -d } glob("*"); delete($all{$_}) for ( map { chomp; $_ } <$fh> ); system('rm', '-ir', $_) for (keys(%all)); __END__ format of dir1/list.name: dir1 dir2 dir3 dir4 dirx
Re: delete all directories which are not in list
by hubb0r (Pilgrim) on Feb 10, 2005 at 07:01 UTC
    Just stick the directory names in a hash and test against them after doing a readdir. If they do not exist in the hash, rmdir them. The caveat is that rmdir will not delete directories that are not empty... you will need to do a bit of recursion to follow the directories into their depths and rmdir/unlink all that is within. I'll leave that part to you.

    my $file = 'list.name'; my @keepers; open FILE, $file or die $!; { local $/ = ','; my @keepers = <FILE>; } close FILE; my %keepers = map { $_ => 1 } @keepers; opendir(DIR, "./") or die $!; my %current_dirs = map { $_ => 1 } readdir(DIR); closedir DIR; foreach my $dir (keys %current_dirs) { next unless (-d $dir); rmdir($dir) unless $keepers{$dir}; }


    Again, the implementation is up to you, but that's a generalized framework for how it can be done.
Re: delete all directories which are not in list
by gube (Parson) on Feb 10, 2005 at 06:52 UTC

    Read all the text and split and put in array and take all directory names in the mentioned direcory names and put in array. compare two and create an array and flow the array and delete the directories.

    I have mentioned the below code

    undef $/; open(IN, "d:\\list.name") || die"Cannot Open file\n"; $str = <IN>; @arr = split(/,|\n/, $str); opendir(DIN, "$ARGV[0]"); @rfiles = readdir(DIN); closedir(DIN); my %seen; # lookup table my @aonly;# answer @seen{@rfiles} = (); foreach $item (@arr) { push(@aonly, $item) unless exists $seen{$item}; } print @aonly; rmdir("$dir\\$_") for (@aonly);

    Gubendran

Re: delete all directories which are not in list
by blazar (Canon) on Feb 10, 2005 at 08:55 UTC
    Minimal example code to accomplish the task you described:
    #!/usr/bin/perl use strict; use warnings; my %have; chomp, $have{$_}++ while <>; rmdir or warn "Can't remove `$': $!\n" for grep /^t\d+$/ && !$have{$_} && -d, <*>; __END__
    Note: this assumes that
    1. you will be running it in the directory in which the directories are to be found with 'list.name' as a cmd line argument,
    2. 'list.name' contains one entry per line,
    3. the directories are empty.
    Of course it's up to you make any necessary modification in case not all of these conditions are satisfied.
Re: delete all directories which are not in list
by gopalr (Priest) on Feb 11, 2005 at 05:58 UTC

    Hi,

    Try the following Modules

    To find the specific file

    File::Find

    To remove the whole directory

    File::Remove