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

Hello all! Just wanted to say thanks in advanced for your help... What I'm trying to do is create a perl script that will do the following....I think the code is correct below, but need further help. Desire result when running the script:
  1. move all logs older than 7 days from a share on a remote server ( \\Testserver01\WeblogicLogs) to a folder that the script will create based on local time and date,
  2. in the process of moving the logs, it will automatically zip it up (with winzip), and name it based on local date and time. I still haven't figured out how to do this with winzip command line option.
  3. Accomplished all this remotely via UNC. Do I have to use the win32::Lanman module for this to work?
Please look at the code below and help me with step 1,2,3. thanks again!
######################################################## # Moving files from one location to # another, creating folder based on local time stamped # # (did not do yet: zipped logs up based on time stamp and # put in the folder.) ######################################################## my $filedir = "\\\\TESTSERVER01\\Weblogiclogs\\"; my $IWlogs = "\\\\TESTServer01\\Weblogiclogs\\*.log*"; # get timestamp to name a file yymmddhhmiss.txt ($sec,$min,$hour,$mday,$mon,$year) = localtime(time); $mon = (1,2,3,4,5,6,7,8,9,10,11,12)[$mon]; if($mon < 10){$mon = "0" . $mon;} # add a leading zero to one- +digit months if($mday < 10){$mday = "0" . $mday;} # add a leading zero to one-di +git days if($hour < 10){$hour = "0" . $hour;} # add a leading zero to one-di +git hours if($min < 10){$min = "0" . $min;} # add a leading zero to one- +digit minutes if($sec < 10){$sec = "0" . $sec;} # add a leading zero to one +-digit seconds $dirname = substr($year,1,3) . $mon . $mday . $hour . $min . $sec; $createDir = $filedir . "\\" . $dirname; if(!-e $createDir) { @args = ( "mkdir", $createDir); system(@args) == 0 or die "error creating $createDir!"; } # move log files to new directory @args = ( "move" , $IWlogs , $createDir ) ; system( @args ) == 0 or die "error moving $IWlogs!";

Edit: Added <code> and <ol> tags. larsen

  • Comment on Moving log files, create folder based on local time/date & zip them up based on local time & date.
  • Select or Download Code

Replies are listed 'Best First'.
Re: Moving log files, create folder based on local time/date & zip them up based on local time & date.
by mjeaton (Hermit) on Sep 09, 2002 at 18:55 UTC
    First suggestion -- use code tags.

    Instead of shelling to winzip, have you considered using Archive::Zip?
    my $zip = Archive::Zip->new(); my $member = $zip->addFile( 'logfile.log' ); my $status = $zip->writeToFileNamed( 'dated_filename.zip' ); die "error somewhere" if $status != AZ_OK;
    As for naming the file, here is what I use:

    my $tempDate = getDate(); my $outfile = $tempDate . ".zip"; sub getDate { my $date; my($day, $mon, $year) = (localtime)[(3,4,5)]; $date = $mon . $day . $year; return $date; }
    The fact that the files are located on another server shouldn't make much difference. Make sure you properly escape the backslashes...this should be enough to get you started.

    mike
      Hi Mike, No I haven't tried the Archive::Zip module. Can I take all the logs in that directory, zip it up and name it based on local time and date with this module? Is so can you give me some example... thanks, anthony
        opendir FILES, $dir_name; my @files = readdir FILES; closedir FILES; my $zip = Archive::Zip->new(); $zip->addFile($_) for @files; my $date = join "_", ((localtime)[3,4,5]); my $status = $zip->writeToFileNamed( "$date.zip" );
        Well, you could either loop through the contents of the directory and use the addFiles method or you could use Archive::Tree. The docs for this module are pretty good and have good examples throughout.

        As long as you're just talking about naming the zip file based on the date and time, the code from my earlier node should cover that.

        mike
Re: Moving log files, create folder based on local time/date & zip them up based on local time & date.
by charnos (Friar) on Sep 09, 2002 at 19:11 UTC
    Two things (well three if you count "Please use code tags"):
    Firstly, I did something similar not too long ago on a Windows network as well...just mount the drive, so that you can easily access the drive as if it were local (I used File::Copy fine this way).

    Secondly, AFAIK, Perl doesn't offer a portable way to get the file creation time. One (messy) way to get around this is through a system call to DOS. dir /TC FILENAME will show the creation time of a file. not pretty or clean, but it will work (you'll have to do a bit of parsing).

    Archive::Zip should do exactly what you want, I believe. It's already installed on your system too, most likely (standard with ActiveState Perl)
Re: Moving log files, create folder based on local time/date & zip them up based on local time & date.
by grinder (Bishop) on Sep 09, 2002 at 20:29 UTC

    I'm not in a windows environment right now, so I can't test whether stat works with UNC specifications, but with a bit of luck the following will let you test for files that are older than seven days (otherwise there's undoubtably a Win32 module that does it for you):

    my $age = (stat $remote)[9]; my $cutoff = time - 86400 * 7; # now less 7 days if( $age < $cutoff ) { # file is older }

    A more compact way of creating the filename (and this is the third time in a week I think I've suggested this) you can do the following:

    my $dirname = sub { sprintf '%02d%02d%02d%02d%02d%02d', $_[0] % 100, @_[1..5] }->((localtime)[5,4,3,2,1,0]);

    It may look complicated, but it saves on all those pesky intermediate variables.


    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'