Friday, June 5, 2009

My faster little find script

I have been using this script for a long time. It certainly could be improved but it has proved invaluable.

##### FILE: find.pl #####


#!/usr/local/bin/perl -w
use strict;
use Getopt::Long;
use Pod::Usage;

my $cmdLine = "rerunRegressionResults.pl @ARGV \n";

my $dateStamp=`date +'%Y-%m-%d-%H%M'`; chomp($dateStamp);
my $output = "";
my $help = 0;
my $grep = "";
my $displayOnly = 0;
my $noGrep = 0;
my $noVim = 0;
my $vimCmd = "";
my $dryRun = 0;
my $cmd = "";
my @fileNames;
my $replaceWithSpace = "~"; # Default is to replace all ~ with spaces.
my $arg = "";
my $verbosity = "";
my $endFind = "";
my @strings;
my $grepArg = "";
my $findRslt = "";
my $findRsltFound = 0;
my $endGrep = "";
my @dirs;
my @findRslts;
my @nots;
my @ands;
my @prunes;
my @sqlResults;
my @outputList;

my $ok = GetOptions(
'displayOnly|do' => \$displayOnly,
'noVim|nv' => \$noVim,
'vimCmd|vc=s' => \$vimCmd,
'dryRun|dr' => \$dryRun,
'dirs=s@' => \@dirs,
'output=s' => \$output,
'endGrep|eg=s' => \$endGrep,
'fileNames|fn=s@' => \@fileNames,
'noGrep|ng' => \$noGrep,
'arg=s' => \$arg,
'verbosity=s' => \$verbosity,
'endFind|ef=s' => \$endFind,
'strings=s@' => \@strings,
'grepArg|ga=s' => \$grepArg,
'nots=s@' => \@nots,
'ands=s@' => \@ands,
'prunes=s@' => \@prunes,
'replaceWithSpace=s' => \$replaceWithSpace,
'help' => \$help
);
if ( !$ok ) { die; }

pod2usage(1) if $help;

push ( @strings , @ARGV );
if ( ( @strings == 0 ) && ( @fileNames == 0 ) ) { die " NO SEARCH STRING OR FILE NAME GIVEN!!! "; }

# Decide the defaults:
if ( @fileNames == 0 ) {
$fileNames[0] = "*";
} else {
if ( @strings == 0 ) { $strings[0] = $fileNames[0]; }
}
if ( @dirs == 0 ) {.
$dirs[0] = "$ENV{'PWD'}";.
}
if ( $vimCmd eq "" ) { $vimCmd = "/usr/local/bin/gvim"; }
if ( $arg eq "" ) { $arg = ""; }
if ( $endFind eq "" ) { $endFind = ""; }
#if ( $grepArg eq "" ) { $grepArg = " -n -I -i -C 3 "; }
if ( $grepArg eq "" ) { $grepArg = " -n -I -i "; }
if ( $output eq "" ) { $output = "~/tmp/find_$strings[0].rslt" }

# Start to build up the find argument

foreach ( @prunes ) { $arg .= " -not \\( -type d -name \"*$_*\" -prune \\) " }
foreach ( @ands ) { $arg .= " -name \"*$_*\" " }
foreach ( @nots ) { $arg .= " -not -name \"*$_*\" " }
if ( @fileNames > 1 ) { $arg .= " \\( "; }
foreach my $index (0..$#fileNames) {
if ( $index > 0 ) { $arg .= " -o "; }
$arg .= " -name \"*$fileNames[$index]*\" ";
}
if ( @fileNames > 1 ) { $arg .= " \\) "; }

# Create the comands and execute
foreach my $string ( @strings ) {
if ( $replaceWithSpace ne "" ) { $string =~ s/$replaceWithSpace/ /g; }
$cmd = "find @dirs $arg $endFind -follow ";
$cmd .= " -print0 | xargs -0 grep $grepArg '$string' $endGrep" unless $noGrep;
print " $cmd \n" unless $verbosity eq "quiet";
$findRslt = qx"$cmd" unless ( $dryRun );
if ( $findRslt =~ m/[a-z]/i ) {
$findRsltFound++;
push ( @outputList , $findRslt );
}
}

if ( ( $findRsltFound < 1 ) && ( ! $dryRun ) ) {.
die " !ERROR! ---> \"$strings[0]\" not found in dir(s) @dirs \n";.
}

# Generate my output
if ( $displayOnly ) {
print @outputList;
} else {
open OUT_FILE, "> $output" or die "cant open $output : $!";
print OUT_FILE @outputList;
close OUT_FILE;
#print @outputList;
unless ( $noVim ) {
my $cmd3;
my $gvimSearch = "";
# The search +/ does not work if using --remote in vim!!! SUCKS
$gvimSearch = " +\"/$strings[0]\" " unless ( $vimCmd =~ m/remote/ );
$cmd3 = "csh -c \"$vimCmd $output $gvimSearch \"";
print " $cmd3 \n";
system("$cmd3") == 0 or die "system $cmd3 failed: $?" unless ( $dryRun );
}
}


__END__

=head1 NAME

find.pl help

=head1 SYNOPSIS

find [options]
Options:
-help This help message
-dirs Directory to search*
-output Alternative output filename
-type Find's type (default = "-type f")
-endGrep|eg Additional grep arguments
-fileNames|fn File Name (default = "*")
-arg Additional find Arguments
-endFind|ef Additional find Arguments for the end of find command
-strings Strings grep will use to search*
-grepArg|ga Alternative grep arguments (default = " -n -I -i -C 3 ")
-nots Additional find logic*
-ands Additional find logic*
-prunes Trims directories from search
-displayOnly|do Does not generate a file
-fno Search for the file name only (no grep)
-noVim|nv Do not open output file with vim
-dryRun|dr Run the script but print the commands do not actually run them

Examples:

find.pl stringtofind
find.pl -fn filetofind stringtofind
find.pl -string stringtofind -fa "-maxdepth 1"
find.pl -s stringtofind -fa "-maxdepth 1"
find.pl stringtofind -fa "-maxdepth 1"
find.pl stringtofind -prune directorynottosearch
find.pl stringtofind -not log
find.pl string_with_spaces -replaceWithSpace _

=cut

No comments:

Post a Comment