#!/usr/bin/perl -w # fileDateTime.pl # # Script is used to check the timestamp (last modified) of all files within the # specified folder, including all files in any subdirectories. The timestamps will # also be used to provide information as to when the file was last modified (in days) # relavent to the current time. The filenames, timestamps, and last modification will # be outputted to a .xls file. # # Author: JHermida # Date : 9/15/2011 THU # Copyright (c) 2011, Cross Country Automotive Services, Inc. ################################################################################ # ALWAYS USE STRICT AND WARNINGS ################################################################################ use strict; use warnings; use Switch; use Cwd; ################################################################################ # MODULES USED (from CPAN) ################################################################################ use File::Find; use File::Copy; use Spreadsheet::WriteExcel; ################################################################################ # MODULES USED (written in-house) ################################################################################ ################################################################################ # GLOBAL VARIABLES ################################################################################ my $num_args = $#ARGV + 1; my $maxDays = -1; # Filters which files will be outputted based on how old the last modification to the file has been made. '-1' denotes all files will be outputted. my $maxDays_ptr = \$maxDays; my $numOfFiles = 0; # Stores the number of files found based on $maxDays my $numOfFiles_ptr = \$numOfFiles; my $workbook = Spreadsheet::WriteExcel->new('timestamps.xls'); my $sheet = $workbook->add_worksheet("Timestamps"); my $columnTitleFormat = $workbook->add_format( bold => 1, size => 12, ); my $rowPos = 1; my $fileCol = 0; my $dateCol = 1; my $dayCol = 2; ################################################################################ # SUBROUTINES DECLARED ################################################################################ sub main(); sub processTimestamp(); ################################################################################ # MAIN LOOP ################################################################################ exit main(); ################################################################################ # SUBROUTINES DEFINED ################################################################################ #------------------------------------------------------------------------------- # main() # # PURPOSE: Main loop # # INPUT: Directory to check modification dates of files # # OUTPUT: List of files and modification dates to timestamps.xls # # SIDE EFFECTS: #------------------------------------------------------------------------------- sub main() { my $inputDir = ''; my $outputDir = ''; # Check arguments passed in by user switch ($num_args){ case 0 { print "\nERROR: No arguments were passed. Command aborted!\n"; help(); } case 1 { chomp($inputDir = $ARGV[0]); #$inputDir =~ s/\\/\//; # Check if the passed directory exists in the system if ( -d $inputDir ) { $outputDir = getcwd; # Output directory will be the pwd } else { print "\nERROR: Invalid input. The input directory may be non-existent. Command aborted!\n"; help(); } } case 2 { chomp($inputDir = $ARGV[0]); # $inputDir must be a valid directory if ( !(-d $inputDir) ) { print "\nERROR: Invalid input. Command aborted!\n"; help(); } # Check if the second argument is an integer (specifying max days) or a directory (specifying the output directory) if ( $ARGV[1] !~ /\D/ ) { # if 2nd argument is an integer $$maxDays_ptr = $ARGV[1]; $outputDir = getcwd; # Output directory will be the pwd } elsif ( -d $ARGV[1] ) { $outputDir = $ARGV[1]; } else { print "\nERROR: Invalid input. The input and/or destination directory may be non-existent, or the specified number of days may be invalid. Command aborted!\n"; help(); } } else { # 1st and 3rd arguments must be existing directories, and 2nd argument must be an integer # Any additional arguments will be ignored if ( -d $ARGV[0] && -d $ARGV[2] && $ARGV[1] !~ /\D/) { chomp($inputDir = $ARGV[0]); chomp($$maxDays_ptr = $ARGV[1]); chomp($outputDir = $ARGV[2]); } else { print "\nERROR: Invalid input. The input and/or destination directory may be non-existent, or the specified number of days may be invalid. Command aborted!\n"; help(); } } } ############################################################################ # This section gives the "invalid top directory at C:/Perl/lib/File/Find.pm line 593" # error when attempting to scan a directory (with no spaces) in the C: drive. Without # this section, the script will enter an infinite loop until the user terminates # # Section removed 9/19, then added back 9/20 - JAH ############################################################################ #Get all files in folder specified, add only directories for search my @directories_to_search = (); my @files = <"$inputDir"*>; foreach my $file ( @files ) { # If the file is a directory, add to @directories_to_search if ( -d $file ) { push ( @directories_to_search, $file ); } } ############################################################################ # Format excel sheet $sheet->write(0, 0, 'File path', $columnTitleFormat); $sheet->write(0, 1, 'Last Modified (Date)', $columnTitleFormat); $sheet->write(0, 2, 'Last Modified (Days)', $columnTitleFormat); $sheet->set_column('A:A', 150); $sheet->set_column('B:B', 30); $sheet->set_column('C:C', 25); # Iterate through files/subdirectores. See File::File module find(\&processTimestamp, @directories_to_search);#$inputDir); # Check if any files were scanned if ( $$numOfFiles_ptr eq '0' ) { $sheet->write($rowPos, $fileCol, "No files found!"); $sheet->write($rowPos, $dateCol, "N/A"); $sheet->write($rowPos, $dayCol, "N/A"); } # Close workbook $workbook->close(); # Print number of files found that were modified based on user input switch ( $$maxDays_ptr ) { case -1 { print "\n[SUCCESS]: $$numOfFiles_ptr files were scanned for their modification date"; } case 0 { print "\n[SUCCESS]: $$numOfFiles_ptr files were modified today"; } case 1 { print "\n[SUCCESS]: $$numOfFiles_ptr files were modified in the last day"; } else { print "\n[SUCCESS]: $$numOfFiles_ptr files were modified in the last $$maxDays_ptr days"; } } # Copy output file if the user has specified a destination if ( $outputDir ne getcwd ) { if ( copy( "timestamps.xls", "$outputDir"."/timestamps.xls" ) ) { print "\n[SUCCESS]: See $outputDir/timestamps.xls\n"; } else { print "\n[FAIL]: Failed to copy timestamps.xls to $outputDir"; } } else { print "\n[SUCCESS]: See " . getcwd . "/timestamps.xls\n" } } #------------------------------------------------------------------------------- # processTimestamp() # # PURPOSE: gets the modification timestamp and number of days all files were last # modified within the target directory # # INPUT: n/a # # OUTPUT: prints information to timestamp.xsl file # # SIDE EFFECTS: #------------------------------------------------------------------------------- sub processTimestamp() { # If file, check modification date #print $_."\n"; if ( !(-d $_) ) { # Get modification date my $mod_date = localtime( (stat $_)[9] ); # Get modification in days my $mod_days = -M $_; # Format of modification date is a decimal, therefore, truncate for whole # $mod_days = sprintf("%d", $mod_days); # Output to excel sheet if ( $$maxDays_ptr >= $mod_days || $$maxDays_ptr eq '-1') { $sheet->write($rowPos, $fileCol, $File::Find::name); $sheet->write($rowPos, $dateCol, $mod_date); $sheet->write($rowPos++, $dayCol, $mod_days); } # Count number of files found if maxDays is specified by user # If maxDays was not specified, count total number of files scanned if ($$maxDays_ptr >= $mod_days && $$maxDays_ptr ne '-1' || $$maxDays_ptr eq '-1') { $$numOfFiles_ptr++; } } } #------------------------------------------------------------------------------- # help() # # PURPOSE: gives help, then exits with errorlevel set to 1. # # INPUT: n/a. # # OUTPUT: Prints help. # # SIDE EFFECTS: n/a #------------------------------------------------------------------------------- sub help() { print < * Indicates the field is required. The "" (without <>) argument specifies the root path of the directory in which to retrieve the modification date of each file within the directory, including all files within each subdirectory. The "" argument filters which files will be outputted based on how old the last modification to the file has been made. This value must be an integer. Enter '0' to see files modified today, '1' to see files modified in the last 24 hours, etc. Leave this field blank to see all file modification dates. The "" argument specifies the directory in which the output file will be created. If this value is not specified, the file will be created in the present working directory. NOTES: 1. If the path contains any spaces, it must be enclosed with parentheses. 2. The script will determine whether the second argument specifies the max number of days or the output destination. ---------- EOF exit 1; }