#!/usr/bin/perl # This script is written to find file copies # It generates report and suggest to choose which copy to delete # Jes's scripts, copyleft ################################################################## use strict; use Time::HiRes qw(gettimeofday tv_interval); use File::Compare; use File::Find; use Term::ANSIColor; my $VERSION = '1.0'; use Getopt::Long qw(:config no_ignore_case); my @bb = gettimeofday; # script's processing begin my (@files, @tfiles); my ($prefix, $help, $greps, $mode, $report); $| = 1; GetOptions("d=s" => \$prefix, "h" => \$help, "g=s"=>\$greps, "s"=>\$mode, "f=s"=>\$report); unless($prefix or $help) { print "enter path(s) to start (comma separated if several):"; while(){ chomp; $prefix = $_; last; } } unless($report or $help) { print "enter path to report file or I'll just write the compare results to STDOUT:"; while(){ chomp; $report = $_; last; } } print "$report" and print color("red"), " file is a directory!\n", color("reset") and exit if (-d $report); my @paths = split (/\,/, $prefix) if ($prefix); if ($prefix) { foreach my $p (@paths) { print "$p" and print color("red"), " is not a directory!\n", color("reset") and exit unless (-d $p); } } print "the directory to start: $prefix\n" unless ($help); print "gathering from directory $prefix ...\n" unless ($help); print color("red"), "\nyou should enter directory to start...\n", color("reset") unless($prefix); &usage unless($prefix); @ARGV = grep {"$_"} @paths unless @ARGV; my @files; find sub {push @files, $File::Find::name}, @ARGV; # files gathering foreach my $f (@files) { # grep files if ($greps) { my @greps = split(/\,/,$greps); push (@tfiles,$f) unless (grep {($f =~/\.$_/)} @greps or -d $f); } else { push (@tfiles,$f) unless (-d $f); } } my $num = scalar @tfiles; print color("blue"), "\n$num files are gathered...\nstarting to compare them...\n", color("reset"); my @pairs; my $ask; unless ($mode) { print "should I use interactive mode (I'll ask about files deleting) [Y/N]?\n"; while(){ chomp; $ask = $_; last; } } my $size = 0; # size of identical files my $freesize = 0; # cleared space on the disk open (REP, ">$report") or print color("red"), "path to report file $report is incorrect!\n", color("reset") and exit if ($report); foreach my $f1 (@tfiles) { my @arr = grep {compare($f1,$_) == 0} @tfiles; # compare files my @checks = grep {$_ eq @arr[0].".".@arr[1]} @pairs if (scalar @arr ==2); push (@pairs, @arr[0].".".@arr[1]) if (scalar @arr ==2); my $fs; if (scalar @arr ==2 and !@checks) { print REP "@arr are identical\n" if ($report); $fs = -s "@arr[0]"; $fs = $fs/1000; print "@arr" and print color("cyan")," are identical, \ntheir size is: ",color("reset") and print "2 * $fs Kb\n"; } unless($mode) { if (scalar @arr ==2 and !@checks and $ask =~/(y|Y)/) { print color("green"), "should I delete first file [1], or second [2], or should I do nothing [enter]?\n", color("reset"); my $action; while(){ chomp; $action = $_; last; } my $del = ($action == 2)?@arr[1]:($action == 1)?@arr[0]:""; if ($del) { print color("blue"), "deleting $del...", color("reset"); unlink $del; print color("blue"), "done!\n", color("reset"); print REP "!!! $del is deleted!\n"; $freesize += $fs; } } } $size += $fs; } my @ee = gettimeofday; # script's processing end my $s = sprintf ("%.2f", tv_interval (\@bb,\@ee)); print color("cyan"), "found no clones!\n", color("reset") unless @pairs; print REP "in $prefix found no clones!\n" if (!@pairs and $report); print color("blue"), "overall size of clones is $size Kb\n", color("reset") if ($size != 0); print REP "\noverall size of clones is $size Kb\n" if ($report and $size != 0); print color("blue"), "released disk space by clone's deleting is $freesize Kb\n", color("reset") if ($size != 0); print REP "released disk space by clone's deleting is $freesize Kb\n" if ($report and $size != 0); print color("blue"), "done for $s sec...\n", color("reset"); print REP "\ndone for $s sec...\n" if ($report); close REP if ($report); &usage if($help); #### OPTIONS #### sub usage() { print <