# Sizefile.pl
$version="2.1.2"; # Sizefile version Number
#
# History
# -------
# v2.1.2 Changed some things that "use warnings;" suggested.
# v2.1.1 Moved some of Subroutines into my own package MySubs.
# v2.1.0 Optimised the search engine some more (Major rewrite of
+ logic).
# v2.0.5 Some more optimisations.
# v2.0.4 Changed it to use Getopt::Long for command line input.
# v2.0.3 Did some Optimisation on the code for speed.
# v2.0.2 Changed the CSV output to a sub routine, and finished b
+asic XLS output.
# v2.0.1 Added beginnings of Excel OLE Support.
# v2.0.0 Changed it to use Win32::Console, (Prettier interface).
# v1.6.2 Changed some cosmetic stuff, Cleaned out some old stuff
+ that wasn't needed.
# v1.6.1 Added History, Added Total Sum to CSV_OUT, Added list o
+f dirs that couldn't be opened.
# v1.6.0 Put updated version of the original search engine back
+in, due to File::Find wont let me control errors concerning opening D
+IRS.
# v1.5.1 Added Pod Documentation
#
#### Load Modules
use Cwd;
use Win32::Console;
use Win32::OLE;
use Getopt::Long;
###### Set default values for incoming variables.
$start_time = localtime($^T);
$original_path = getcwd();
$console = new Win32::Console(STD_OUTPUT_HANDLE);
($X,$Y) = $console->Size();
GetOptions(
"path=s" => \$SEARCH_PATH,
"file=s" => \$FILES_IN,
"gt=s" => \$MORE_THAN,
"lt=s" => \$LESS_THAN,
"list=s" => \$LIST_FILE,
"help!" => \$HELP,
"prompt!" => \$PROMPT,
"true!" => \$REAL_MEGABYTE,
"open!" => \$OPEN_CSV,
"xls!" => \$DOEXCEL,
"examples!" => \$EXAMPLES
) || &Help_for_Sizefile;
&Help_for_Sizefile if $HELP;
&show_examples if $EXAMPLES;
&Prompt_for_input if $PROMPT;
if ($LIST_FILE && (-e $LIST_FILE)) {
open (list_in_from_file, "<$LIST_FILE") || die "\n*** ERROR OPENIN
+G $FILE ***\n";
chomp (@files_to_search_for = <list_in_from_file>);
close list_in_from_file;
} else {
@files_to_search_for = split /;/,$FILES_IN || '*.*'; # Default sea
+rch if none specified
}
$path_to_search = $SEARCH_PATH || getcwd(); # Default p
+ath if none specified = Current Path
$file_must_be_less_than = $LESS_THAN || "9999M"; # Default less
+ than size if none specified
$file_must_be_more_than = $MORE_THAN || "0"; # Default less tha
+n size if none specified
############################
### Signal Handlers ###
$SIG{__WARN__} = \&warn_handle;
$SIG{STOP} = \&sig_int;
##########################
$console->Title ("Sizefile.pl v$version");
&CONSOLE_BORDER();
$rect = $console->ReadRect(2, 9, $X - 3, $Y - 3);
CENTER_LINE("Sizefile v$version by Martin Bowers", 2, $FG_YELLOW);
CENTER_LINE("--------------------------------", 3, $FG_RED);
chdir $path_to_search || die "\n*** Error opening $path_to_search ***\
+n"; # this sets the path into a true filename
$path_to_search = getcwd();
$path_to_search =~ s/\/$//gi;
@orig_files_to_search_for = @files_to_search_for;
PRINT_LINE("Path = $path_to_search", 2, 4, $FG_GRAY);
map {$LIST .= "$_ "} @files_to_search_for;
PRINT_LINE("File = ".substr($LIST, 0, $X - 14)."...", 2, 5, $FG_GRAY)
+if length($LIST) > $X - 20;
PRINT_LINE("File = @files_to_search_for", 2, 5, $FG_GRAY) if length($L
+IST) < $X - 20;
undef $LIST;
PRINT_LINE("> $file_must_be_more_than", 60, 4, $FG_GRAY);
PRINT_LINE("< $file_must_be_less_than", 70, 4, $FG_GRAY);
PRINT_LINE("Started @ $start_time", 2, 7, $FG_YELLOW);
foreach (@files_to_search_for) {
s/\./\\\./gi;
s/\*/.*/gi;
s/\?/./gi;
}
$F = join '$|^', @files_to_search_for;
foreach ($file_must_be_more_than, $file_must_be_less_than) {
if (/k/i) {
if ($REAL_MEGABYTE) {
s/k//i;
$_ *= 1024;
} else {
s/k/000/i;
}
} elsif (/m/i) {
if ($REAL_MEGABYTE) {
s/m//i;
$_ *= 1048576;
} else {
s/m/000000/i;
}
}
}
die "\n*** ERROR ***\n\n -lt < -gt\n\n*** ERROR ***\n" if $file_must_
+be_less_than < $file_must_be_more_than;
SEARCH($path_to_search);
$end_time = localtime;
if ($DOEXCEL) {&do_excel_out;} else {&do_csv_out;}
PRINT_LINE("Finished @ $end_time", 2, $Y - 3, $FG_YELLOW);
PRINT_LINE("Total size = ".&COMMA($total_size)." bytes in ".&COMMA(sca
+lar @files_found)." files", 2, $Y - 2, $FG_YELLOW) if scalar @files_f
+ound >0;
PRINT_LINE("No files found matching that critera!", 2, $Y - 3, $FG_LIG
+HTRED) if scalar @files_found <1;
if ($OPEN_CSV && scalar @files_found >0) {
chdir $original_path;
exec "sizefile.csv";
}
print "\n"x $Y;
exit;
##### SUBROUTINES #####
sub Help_for_Sizefile { # Help subroutine, prints help
$console->Title ("Sizefile.pl v$version");
console_border();
CENTER_LINE("Sizefile v$version by Martin Bowers",2,$FG_YELLOW);
CENTER_LINE("--------------------------------",3,$FG_RED);
my $line = 4;
PRINT_LINE("Sizefile.pl HELP",3,$line++,$FG_YELLOW); $line++;
PRINT_LINE("sizefile.pl [-path path] [-file filename] [-gt size] [
+-lt size]",3,$line++,$FG_WHITE); $line++;
PRINT_LINE("This program has five parameters:",3,$line++,$FG_WHITE
+); $line++;
PRINT_LINE(" -path path specifies the path of the se
+arch",3,$line++,$FG_WHITE);
PRINT_LINE(" -file file[,file,,,] the file name to search for"
+,3,$line++,$FG_WHITE);
PRINT_LINE(" -gt size file must be greater than th
+is size",3,$line++,$FG_WHITE);
PRINT_LINE(" -lt size file must be less than this
+size",3,$line++,$FG_WHITE);
PRINT_LINE(" -true Set GT/LT to use real megaby
+tes (1,048,576bytes)",3,$line++,$FG_WHITE);
PRINT_LINE(" -list file.txt get file list from file.txt"
+,3,$line++,$FG_WHITE);
PRINT_LINE(" -prompt prompts user for details",3,
+$line++,$FG_WHITE);
PRINT_LINE(" -xls generates XLS file instead o
+f CSV",3,$line++,$FG_WHITE);
PRINT_LINE(" -examples displays examples",3,$line++
+,$FG_WHITE);
PRINT_LINE(" -help this screen",3,$line++,$FG_W
+HITE);
exit;
}
sub show_examples {
my $line=4;
PRINT_LINE("Examples:",3,$line++,$FG_YELLOW);
$line++;
PRINT_LINE('sizefile.pl -path \\\\sau01dat01\z$ find all
+ files on <--',3,$line++,$FG_WHITE);
PRINT_LINE('sizefile.pl -file *.bat find *.bat
+ file here and down',3,$line++,$FG_WHITE);
PRINT_LINE('sizefile.pl -gt 10m find file
+> than 10Mb',3,$line++,$FG_WHITE);
PRINT_LINE('sizefile.pl -lt 10k find file
+< than 10Kb',3,$line++,$FG_WHITE);
PRINT_LINE('sizefile.pl -path d:\ -file *.dl? -gt 10m find *.dl?
+ on d:\ > than 10m',3,$line++,$FG_WHITE);
PRINT_LINE('sizefile.pl -path d:\ -file *.exe,*.com find *.com
+ and *.exe',3,$line++,$FG_WHITE);
PRINT_LINE('sizefile.pl -file [az]*.* a*.dll and
+ z*.dll',3,$line++,$FG_WHITE);
PRINT_LINE('sizefile.pl -file [a..l]*.* a*.*,b*.*,
+ ... , l*.* ',3,$line++,$FG_WHITE);
exit;
}
sub Prompt_for_input {
print "\nPlease enter what you want to search for: ";
chomp (my $tempfile = <STDIN>);
@files_to_search_for = split /,/,$tempfile if ($tempfile ne '');
print "Please enter the path for the search: ";
chomp (my $temppath = <STDIN>);
if ($temppath ne '') {$path_to_search = $temppath;}
print "The file should be greater than: ";
chomp (my $tempfsgt = <STDIN>);
if ($tempfsgt ne '') {$file_must_be_more_than = $tempfsgt;}
print "The file should be less than: ";
chomp (my $tempfslt = <STDIN>);
if ($tempfslt ne '') {$file_must_be_less_than = $tempfslt;}
print "\n";
}
sub ole_out {
my $TEXT = shift;
my $COL = shift;
my $ROW = shift;
$sheet->Cells($ROW,$COL)->{Value} = $TEXT;
}
sub warn_handle {
my $time = localtime;
print "$time\t***WARN***\t $_[0]";
}
sub sig_int {
my $signal = shift;
close csv_out;
print "SOMEONE WANTS OUT!!!!!\n"x20;
$SIG{$signal} = \&sig_int;
}
sub do_excel_out {
# use existing instance if Excel is already running
eval {$EXCEL = Win32::OLE->GetActiveObject('Excel.Application')};
die "Excel not installed" if $@;
unless (defined $EXCEL) {
$EXCEL = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit
+;})
or die "Oops, cannot start Excel";
}
# get a new workbook
$book = $EXCEL->Workbooks->Add;
$sheet = $book->Worksheets(1);
$book->{"ActiveSheet"}->{"Name"} = "Sizefile";
ole_out("Generated by Sizefile v$version - written by Martin Bower
+s", 1, 1);
ole_out("Started @ $start_time", 1, 2);
ole_out("Path = $path_to_search", 1, 3);
ole_out("File = @orig_files_to_search_for", 2, 3);
ole_out("> $file_must_be_more_than but", 3, 3);
ole_out("< $file_must_be_less_than", 4, 3);
ole_out("Filename", 1, 5);
ole_out("Filesize", 2, 5);
ole_out("Access", 3, 5);
ole_out("Modified", 4, 5);
my $start_pos = 6;
map {
my ($filename,$filesize,$access,$modified) = split /,/,$_;
ole_out($filename, 1, $start_pos);
ole_out($filesize, 2, $start_pos);
ole_out($access, 3, $start_pos);
ole_out($modified, 4, $start_pos);
$start_pos++;
} @files_found;
ole_out("Total Sum", 1, scalar @files_found + 6);
ole_out("=sum(b6:b". (scalar @files_found + 5) .")", 2, scalar @fi
+les_found + 6);
ole_out("Finished @ $end_time", 1, scalar @files_found + 8);
$book->SaveAs( "$original_path/SIZEFILE.xls");
undef $book;
undef $EXCEL;
}
sub do_csv_out {
open (csv_out, ">$original_path/sizefile.csv") || die "*** ERROR O
+PENING sizefile.csv - File may be in use ***\n";
print csv_out "Generated by Sizefile v$version - written by Martin
+ Bowers\n";
print csv_out "Started @ $start_time\n\n";
print csv_out "\nPath = $path_to_search\nFile = @orig_files_to_sea
+rch_for\n> $file_must_be_more_than but < $file_must_be_less_than\n";
print csv_out "Filename,Filesize,Access,Modified\n";
map {print csv_out "$_\n";} @files_found;
print csv_out "Total Sum,=sum(b9:b".(scalar @files_found + 8).")\n
+" if scalar @files_found >0;
map {print csv_out $_;} @dir_error_list;
print csv_out "\n\nFinished @ $end_time";
close csv_out || warn "*** ERROR CLOSING CSV_OUT ***\n";
}
sub SEARCH {
push @PATH, shift;
my $PATH = join "/", @PATH;
opendir (DIR, "$PATH/") || &dir_error($PATH, $COL, $ROW);
my @FILES = readdir(DIR);
closedir DIR;
CENTER_LINE("-" x $X, $Y - 1, $FG_WHITE);
CENTER_LINE($PATH, $Y - 1, $FG_YELLOW);
foreach $FILE (@FILES) {
$COL = $COL || 1;
$ROW = $ROW || 9;
if ($COL > $X - 4) {
$COL=1;
$ROW++;
if ($ROW > $Y - 5) {
$ROW = 9;
$console->WriteRect($rect, 2, 9, $X - 3, $Y - 3)
}
}
$COL++;
if (-d "$PATH/$FILE") {
PRINT_LINE(".", $COL, $ROW, $FG_WHITE);
&SEARCH($FILE) if ($FILE !~ /^\./);
} else {
if ($FILE =~ /^$F$/gi) {
my $size_of_file = -s "$PATH/$FILE";
if ($size_of_file >= $file_must_be_more_than && $size_
+of_file <= $file_must_be_less_than) {
$total_size += $size_of_file;
my @file_info = stat "$PATH/$FILE";
my @raw_access_time = localtime($file_info[8]);
my @raw_modify_time = localtime($file_info[9]);
undef @file_info;
my $last_access_date = ($raw_access_time[3])."/".(
+$raw_access_time[4]+1)."/".($raw_access_time[5]+1900);
my $last_modify_date = ($raw_modify_time[3])."/".(
+$raw_modify_time[4]+1)."/".($raw_modify_time[5]+1900);
PRINT_LINE("*", $COL, $ROW, $FG_LIGHTGREEN);
push @files_found, "$PATH/$FILE,$size_of_file,$las
+t_access_date,$last_modify_date";
} else {
$COL--;
}
} else {
$COL--;
}
}
}
pop @PATH;
return $total_size;
}
sub dir_error { # for when opendir fails
my $DIR = shift;
my $COL = shift;
my $ROW = shift;
PRINT_LINE("X", $COL, $ROW, $FG_LIGHTRED);
push @dir_error_list, "\nERROR opening DIR $DIR";
undef $DIR, $COL, $ROW;
}
sub COMMA {
local $_ = shift;
1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
return $_;
}
sub CONSOLE_BORDER {
$::console->Cls($::FG_WHITE | $::BG_BLUE);
$::console->FillChar('-', $::X, 0, 0);
for $y (1..$::Y - 1) {
$::console->FillChar('|', 1, 0, $y);
$::console->FillChar('|', 1, $::X - 1, $y);
}
$::console->FillChar('-', $::X, 0, $::Y - 1);
}
sub CENTER_LINE {
my $string= shift;
my $line_no = shift;
my $COLOR = shift || $::FG_LIGHTRED;
my $line_length = length($string);
my $center = int(($::X - $line_length) / 2);
$::console->FillAttr( $COLOR | $::BG_BLUE, $line_length, $center,
+$line_no);
$::console->WriteChar($string, $center, $line_no);
}
sub PRINT_LINE {
my $string= shift;
my $col = shift;
my $row = shift;
my $COLOR = shift || $::FG_LIGHTRED;
my $line_length = length($string);
$::console->FillAttr( $COLOR | $::BG_BLUE, $line_length, $col, $ro
+w);
$::console->WriteChar($string, $col, $row);
undef $string, $col, $row, $color, $line_length;
}
sub CLR_LINE {
my $LINE = shift;
$::console->WriteChar(" " x ($::X - 3), 1 ,$LINE);
undef $LINE;
}
In reply to Sizefile
by BatGnat
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.