Hey Patricia,

Thursday, July 19, 2001, 10:49:11 AM, my MUA believes you used
Internet Mail Service (5.5.2653.19) to write:

DPA> Okay I really am a newbie.  This whole perl thing has confused
DPA> me.  (Any suggestions on clarification to my confusion of the
DPA> language would be appreciated as well)

DPA> I am trying to create a script on an NT machine that will search through the
DPA> directories and find specific directories/folders and pars through them to
DPA> delete their contents and work it's way back out deleting as it goes.  For
DPA> example I want to delete all folders that start with  _vti but I can't
DPA> delete this until everything inside is deleted so I have to find this go
DPA> inside delete everything inside and then delete the folder and continue
DPA> doing this through an entire drive.  

DPA> Is there a module I should be using? Can anyone give me suggestions as to
DPA> where to find info on such a script?  I have the Programming Perl book from
DPA> Oreilly but it seems to be giving me info on UNIX and not so much for
DPA> windows.....

I had a similar need, and got some help from this list to come up with
the following...  Not complete (especially the help), but it works.

Comments welcome <g>

<snip>

#!/perl -w

use strict;
use diagnostics;
use File::Find;
use File::Copy;
use File::Spec::Functions;
use File::Basename;
use XML::Simple;
use Data::Dumper; # print Dumper($config);
my (%Cfg, $DTS, $config, $RunningConfig, %Ext, $AGE, $Drive, $PassType, $StartDir, 
$Archive, $PurgeDir, $Extensions, $StartPath); # set in BEGIN
# do I need all these variables in the my statement?

finddepth(\&MoveDecision, $StartPath); # a function of File:Find

sub MoveDecision { # finddepth calls this for each hit
    # $File::Find::dir contains the current directory name
    my $dir = $File::Find::dir;
    # we are creating $newdir with the $Archive top dir
    (my $newdir = $dir) =~ s/$StartDir/$Archive/;
    #(my $newdir = $File::Find::dir) =~ s/$StartDir/$Archive/;
    my $lcNewDir = lc($newdir); # Ignore case for the "if"s

    if ($PassType eq 'AGE') {
        if (-M > $AGE) {
            &DoTheMove($newdir, $dir);
        }
    } elsif ($PassType eq 'DIR') {
        $PurgeDir = lc($PurgeDir);
        if ($lcNewDir =~ /$PurgeDir/) {
            &DoTheMove($newdir, $dir);
        }
    } elsif ($PassType eq 'EXT') {
        if (ByExt($Extensions) eq "ExtMatch") {
            &DoTheMove($newdir, $dir);
        }
    }
}

sub BuildConfig {
    $Drive = $config->{Drive};
    $StartDir = $config->{StartDir};
    $Archive = $DTS; # Created in root of $Drive

    $AGE = $config->{AGE};  # days
    $PurgeDir = $config->{PurgeDir}; # Directory string to look for.
    $Extensions = lc($config->{Extensions});

    $StartPath = "$Drive/$StartDir";

    # Set vars to determin how we are going to run!

    $PassType = uc($config->{PassType});
    my $CommonConfig = "
  PassType = $PassType\n
 StartPath = $StartPath
   Archive = $Drive/$Archive";

    if ($PassType eq 'AGE') {
          $PurgeDir = "all"; # Not used in this configuration, so do everything
          $Extensions = "all"; # Not used in this configuration, so do everything
        $RunningConfig = $CommonConfig . "
       Age = $AGE days";
    } elsif ($PassType eq 'DIR') {
          $AGE = 0; # Not used in this configuration, so do everything
          $Extensions = "all"; # Not used in this configuration, so do everything
        $RunningConfig = $CommonConfig . "
  PurgeDir = $PurgeDir ";
    } elsif ($PassType eq 'EXT') {
          $AGE = 0; # Not used in this configuration, so do everything
          $PurgeDir = "all"; # Not used in this configuration, so do everything
        $RunningConfig = $CommonConfig . "
Extensions = $Extensions ";
    } else {
        print "\n\tError, Check your xml file\n";
        exit;
    }
    #print qq[\n\tAGE=$AGE, Extensions=$Extensions, PurgeDir=$PurgeDir\n];#testing
}

sub ByExt {
    my $ExtList = shift; # set $ExtList to 1st element of @_
    return "ExtMatch" if ($ExtList =~ /all/); # this is to catch all ext's
    return 0 if (-d); # get out if we are processing a dir
    my @FN = split (/\./, $_);
    if (@FN > 1) {
        return "ExtMatch" if ($ExtList =~ /$FN[-1]/);
        #print "\n   EXT-MATCH!\t$FN[-1]" if ($ExtList =~ /$FN[-1]/); # testing
    }
}

sub DoTheMove {
    my $newdir = shift; # set $dir to 1st element of @_ ($newdir)
    my $dir = shift; # set $dir to 1st element of @_ ($newdir)
    GenDirs($newdir); # call the sub to create direcotries
    return "isDir" if (-d);
    if (lc($config->{Copy}) eq "copy") {
        copy($_, catfile($newdir, $_));
    } else {
        move($_, catfile($newdir, $_));
    }
    LOG("\n".catfile($dir, $_));
}

sub GenDirs { # create the dirs if they do not exist
    my $dir = shift; # set $dir to 1st element of @_ ($newdir)
    return if -d $dir; # return from sub if $dir is a directory
    my $parent = dirname($dir); # $parent is set to the path of $dir
        # run GenDirs again unless $parent is a dir (if exists)
    GenDirs($parent) unless -d $parent;
        mkdir $dir; # create a directory (what this sub does)
}

sub CreateCFG {
    my $FN = shift; my $cfgFN = $FN . ".xml";
    print "\n\tThe config file does not exist, creating $cfgFN.";
    print "\n\tPlease check that the settings are what you need.\n";
    my $xmlCfgContents = qq[
<config>
    <!-- Character Case does not matter, but watch out for leading or trailing spaces! 
-->

    <PassType>DIR</PassType>
    <!-- Valid PassType entries: DIR EXT AGE -->

    <Drive>d:</Drive>
    <StartDir>!users</StartDir>

    <AGE>2</AGE>
    <PurgeDir>New Folder</PurgeDir>
    <Extensions>COM EXE GIF JPEG JPG MP3 MPEG MPG</Extensions>

    <Copy>copy</Copy>
    <!-- The "Copy" tag runs a copy if the value is "copy" and a "move" if it is 
anything else -->
</config>
];
    open (xmlCfg, ">$cfgFN") || die "Can't create $cfgFN : $!";
    print xmlCfg $xmlCfgContents; # Create config file
    print        $xmlCfgContents; # & write to STDOUT
    close xmlCfg;
    CreateHTMLdoc($FN);
}

sub LOG { #Where do we open the File Handle Log?
    my        $LogEntry = shift;
    print     $LogEntry; # Create Log file
    print Log $LogEntry; # Create Log file
}

sub CreateHTMLdoc { # change this to POD format!
    my $FN = shift; my $docFN = $FN . "Doc.html";
    my $xmlCfgContents = shift;
    open(Doc, ">$docFN") || die "Can't create $FN : $!";
    my $POD = `pod2html $0`; print Doc $POD;



    print Doc <<endDOCS; # Doc's here.
    <html> <head>
       <meta name="Author" content="Timothy L Musson">
       <title>Network Drive Cleanup Utility $0</title>
    </head> <body>
    <b>Network Drive Cleanup Utility</b> ($0)<p>

    The intent is to run this in 3 general passes:
    Directory, Extension, then Age.<p>
    This way the Directory pass gets both extensions and old files
        (less for subsuquent passes).  Then the Extension pass gets
        old files, and finaly all the Old files that were not
        archived by previous passes.
    <pre>
    1. <b>Directory</b> pass - Archive Directories (Program Files, WinNT, etc)
        Set AGE = 1
        Set Extensions = All #Note, if first ext is "All", we do them All!
        PurgeDir = Program Files #only 1 directory per pass!

    2. <b>Extension</b> pass - Archive files by Extension
Not implemented yet!
        Set AGE = 1
        Set Extensions = com exe gif jpeg jpg mp3 mpeg mpg
        Set PurgeDir = Scan All Dirs

    3. File <b>Age</b> pass  - Archive files yb Age (in days)
        Set AGE = 365 #days
        Set Extensions = All
        Set PurgeDir = Scan All Dirs
    </pre>
    Note: this is all a file move...  This means that the old
        directories are left intact.  Will have to skulk out and
        get them at another time.

    </body> </html>
endDOCS
    close Doc;
    exit;
}

BEGIN { # $DTS, ><.cfg, >*Doc.html
    #Sec=$T[0],M=1,H=2, mDay=3,Mon=4,Yr=5, wDay=6,yDay=7, isdst=8
    my (@T) = localtime(time); $T[5]=1900+$T[5]; ++$T[4];
    $DTS = qq[$T[5]y$T[4]m$T[3]d$T[2]h$T[1]m$T[0]s]; #
    my @FN = split (/\./, $0); # put Filename & Ext in @FN elements
    if (!-e "$FN[0].xml") { # Create a config file (if not exists)
        CreateCFG($FN[0]);
    } else { # Read config";
        $config = XMLin();
        BuildConfig();
    } # end if/else create/read .cfg
    my $CopyNote = "\n\tNote: Running a " . lc($config->{Copy}) . "\n" if 
$config->{Copy};

    my $logFN = $Archive. ".log";
    #print "The logFN is ", $logFN;
    open  (Log, ">>$logFN");# || die "Can't create $logFN : $!";
    LOG($CopyNote."$RunningConfig"."\n\nStarting at $T[2]:$T[1]:$T[0]\n");

#exit; # testing
} # end BEGIN

END { # write the ending time to the log file and screen.
    #Sec=$T[0],M=1,H=2, mDay=3,Mon=4,Yr=5, wDay=6,yDay=7, isdst=8
    my (@T) = localtime(time); $T[5]=1900+$T[5]; ++$T[4];
    $DTS = qq[$T[5]y$T[4]m$T[3]d$T[2]h$T[1]m$T[0]s]; #

    LOG("\n\nStarting at $T[2]:$T[1]:$T[0]\n");
}

=head1 NAME

<DriveCleanup> - Archive network file system files

=head1 SYNOPSIS

B<DriveCleanup> reads (or creates if it does not exist) DriveCleanup.xml - the
configuration file.  Then moves files to another directory, maintaining the directory
structure, for archive.

=head1 DESCRIPTION

F<DriveCleanup> recurses through the directery structure & moves files
(retaining the directory structure) to a new toplevel directory.  The new
top level directory is generated based on the current Date Time Stamp and
is in the format of YYYYyMMmDDdHHhMMmSSs (the upper case letters will be
numbers).

=head1 OPTIONS

=over 5

=item B<DriveCleanup.xml>
looks like this

<config>
    <!-- Character Case does not matter, but watch out for leading or trailing spaces! 
-->

    <PassType>DIR</PassType>
    <!-- Valid PassType entries: DIR EXT AGE -->

    <Drive>d:</Drive>
    <StartDir>!users</StartDir>

    <AGE>2</AGE>
    <PurgeDir>New Folder</PurgeDir>
    <Extensions>COM EXE GIF JPEG JPG MP3 MPEG MPG</Extensions>

    <Copy>copy</Copy>
    <!-- The "Copy" tag runs a copy if the value is "copy" and a "move" if it is 
anything else -->
</config>

=back

=head1 VERSION

This is Version 1.0

=head1 AUTHOR

=over 5

=item Coded by

Tim Musson <[EMAIL PROTECTED]>

=item written on

100% recycled electrons!

=back

=head1 ToDo:

=over 5

=item *

I can't think of anything... <g>

=back

=head1 Change History:

=over 5

=item *

7/2/2001 - changed config format to xml using XML::Simple

=item *

7/3/2001d - added POD

=item *

7/9/2001a

=over 5

=item *

both RO and Excel Open files are copied.

=item *

Move - Excel Open file was not moved, code just kept going <g> RO file was moved.

=item *

html now outputs POD - still need to strip old html output.

=over 5

=item *

7/10/2001 - log file is created in same dir as DriveCleanup is run from.

=back

=cut

</snip>

-- 
[EMAIL PROTECTED]
Using The Bat! (http://www.ritlabs.com/the_bat/) eMail v1.53d
Windows NT 5.0.2195 (Service Pack 1)
I have an imaginary friend who refuses to play with me.


NetZero Platinum
No Banner Ads and Unlimited Access
Sign Up Today - Only $9.95 per month!
http://www.netzero.net

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to