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

Hi guys,

I am fairly new with perl. Would really appreciate some help. Here is what I am trying to have the script do:

1. change directory to my desired directory: /glb/home/usjak8/myperl

2. There are 4 directories under that directory: dir1, dir2, dir3, dir4.

3. I would like to recursively delete dir1, dir2 and dir4 with all the files under them removed as well.

4. I want to leave dir3 alone.

5. Once dir1, dir2 and dir4 are deleted I want to log the message in a file saying that these are the files that are deleted.

6. File names will change every week except for dir3.

7. No need to print anything as this script will run via cron on every Monday morning at 5am. The only way administrator would know that the directories are deleted is by looking at the output file showing the deleted directories or cd'ing to the /glb/home/usjak8/myperl directory and doing an ls there.

Thanks in advance for your help.

Javed

  • Comment on Removing all directories recursively except one

Replies are listed 'Best First'.
Re: Removing all directories recursively except one
by skx (Parson) on Aug 06, 2014 at 06:49 UTC

    Normally people are pretty good at helping here, if you show what you've done and don't just request that people write code for you, for free.

    I'd suggest you probably want to start by looking at the File::Find module, as this lets you recurse easily and then take actions on the files.

    That said if you just want to get the damn thing done why not use the find command?

    find /glb/home/usjak8/myperl ! -iname 'dir3' -print -delete
    

    That will print and delete anything beneath "/glb/home/.." which doesn't have dir3 in the name. If you wished to log just add "| tee ~/delete.log" on the end.

    Steve
    --
Re: Removing all directories recursively except one
by toolic (Bishop) on Aug 05, 2014 at 18:57 UTC
Re: Removing all directories recursively except one
by CountZero (Bishop) on Aug 06, 2014 at 05:52 UTC
    In your log-file, do you want to see the list of all files deleted or only the names of the top-directories or of all directories deleted?

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: Removing all directories recursively except one
by Anonymous Monk on Aug 06, 2014 at 07:45 UTC
    Good luck :) cpanm Path::Tiny
    #!/usr/bin/perl -- ## ## ## perltidy -olq -csc -csci=3 -cscl="sub : BEGIN END " -otr -opr -ce +-nibc -i=4 -pt=0 "-nsak=*" ## perltidy -olq -csc -csci=10 -cscl="sub : BEGIN END if " -otr -opr +-ce -nibc -i=4 -pt=0 "-nsak=*" #!/usr/bin/perl -- use strict; use warnings; use Path::Tiny qw/ tempdir path /; Main( @ARGV ); exit( 0 ); sub Main { my $dad = tempdir; MakeKids( $dad ); for my $kid ( NotKids( $dad, 2, 2, 2 ) ) { ListAll( $dad ); path( $kid )->remove_tree; } ListAll( $dad ); $dad->remove_tree; ## cleanup tempdir } ## end sub Main sub NotKids { my $dad = shift; my %notKid = map { $_ => !!1 } @_; my @nots; for my $kid ( $dad->children ) { if( not exists $notKid{ $kid->basename } ) { push @nots, $kid; } } return @nots; } ## end sub NotKids sub ListAll { my( $dad ) = @_; my $iter = path( $dad )->iterator( { recurse => 1, } ); while( my $kid = $iter->() ) { print "$kid\n"; } print "\n"; } ## end sub ListAll sub MakeKids { my( $dad ) = @_; for my $ix ( 1 .. 3 ) { for my $iy ( 1 .. 3 ) { my $kid = path( $dad, $ix, $iy ); $kid->touchpath->spew( "$kid" ); } } } ## end sub MakeKids

    Perl Tutorial Hub

Re: Removing all directories recursively except one
by locked_user sundialsvc4 (Abbot) on Aug 07, 2014 at 02:50 UTC

    A few thought-questions and food-for-thought bits here:

    (1)   Might this be an “XY Problem?”   Might the thing that you are “ultimately trying to accomplish,” in fact be a well-known problem that has been addressed already ... say, by a command such as logrotate?   “Writing a brand-new program,” in whatever language it might be, is a pretty-cool thing to have done, unless (heh, heh ...) at the end you discover that someone else, a dozen years ago or more, already did it infinitely-better.   (Ouch!)   Frankly, this requirement smells a lot like just such a situation.

    (1a)   I say this from “red-faced experience.”   ’Nuff said ...

    (1b)   To make this assessment fairly, you must “drag yourself, kicking-and-screaming, away from How,” and force yourself to stare at What.

    (2)   If you do find that you need to monkey with a directory-structure in this way, let me strongly advise you to write your code so that it does the job in two distinct stages.   First, it should scan the target directory to gather-up a list of contained directories ... remembering (Ouch! #2 ...) to ignore "." and "..".   Fully complete the scan, then process your list.   In other words, do not attempt to manipulate the directory structure during the scan.