BrianAtWork
Programmer
Hello everyone!
I have a directory that is very large (contains over 4,000 files in it), so "grep string *.sh" does not work because *.sh returns to many files for grep. Also, many of the files contain lines that are longer than 2048 bytes long - another condition that causes grep to fail.
This is on a UNIX-AIX box.
I wrote a peice of perl code to use in substitute of the native grep command. It works perfectly, but it runs a few seconds slower than grep.
I use a "-l" option if the use wants to display every line that contains their match (opposite of grep -l). If the user doesn't use the "-l" option, only the file is displayed, and the script jumps to the next file... I use a variable to hold the name of the subroutine that the script should use in this case, and because of this I am unable to "use strict;"...
Here is the code:
My main question is are there any places I can optimize my code to help it run faster?
Please feel free to criticize!![[peace] [peace] [peace]](/data/assets/smilies/peace.gif)
Plus, maybe this post can help other people?
Thanks in advance!
Brian
I have a directory that is very large (contains over 4,000 files in it), so "grep string *.sh" does not work because *.sh returns to many files for grep. Also, many of the files contain lines that are longer than 2048 bytes long - another condition that causes grep to fail.
This is on a UNIX-AIX box.
I wrote a peice of perl code to use in substitute of the native grep command. It works perfectly, but it runs a few seconds slower than grep.
I use a "-l" option if the use wants to display every line that contains their match (opposite of grep -l). If the user doesn't use the "-l" option, only the file is displayed, and the script jumps to the next file... I use a variable to hold the name of the subroutine that the script should use in this case, and because of this I am unable to "use strict;"...
Here is the code:
Code:
#!/usr/bin/perl
# $Id: pgrep.pl,v 1.3 2005/01/03 18:11:04 brian Exp brian$
use Getopt::Std;
use vars qw($opt_s $opt_o $opt_l $opt_i);
my $ONEARG=1; #Set a flag to see the user is passing just the string
if ($#ARGV != 0 or $ARGV[0] =~ /^\-.*[^s].*/ ){
$ONEARG = 0;
getopts("s:o:li"); #calls getopt function to store command line options
} #end if
else { #if there are no command line flags, set
$opt_s=$ARGV[0]; #the string variable to the incoming argument.
} #end else
#################DELCARE GLOBALS#######################
my $helpmsg=qq(\nUsage: pgrep.pl 'search string'
or pgrep.pl string
or pgrep.pl -i -l -s 'search string' -o /path/results.out
****Exiting script!\n\n);
if ( ! $ONEARG and ! $opt_s ) { #If there are flags, but not the -s flag
print STDOUT $helpmsg;
exit;
} #end if
select(STDOUT);#default: print to STDOUT
if ($opt_o) { #If the user wants output to go to an outpufile.
open(OUTFILE,">$opt_o") or die "Unable to open output file: $opt_o\n";
print STDOUT "Output will be saved to $opt_o\n";
select(OUTFILE);
} #end if
my $listsub="files_only"; #default: List files that contain the match
$listsub="all_lines" if ($opt_l); #if opt_l, list every line that matches...
my $re = qr/${opt_s}/o; #default: case sensitive search
$re = qr/${opt_s}/io if ($opt_i); #if opt_i, case INsensitive search
print "Files that contain '$opt_s':\n\n";
&test_it; #run the subroutine
#########################################################
sub test_it {
opendir(DIR,'.') or die "Unable to read current directory.\n";
my @allfiles = readdir(DIR); #read in all files in directory.
closedir(DIR);
shift @allfiles if $allfiles[0] =~ /^\.\.?$/; #get rid of . and .. in the list
shift @allfiles if $allfiles[0] =~ /^\.\.?$/;
DIRLOOP: foreach my $file (@allfiles) { #Read in each file.
next DIRLOOP if (! -r $file); #Check if file is readable or not.
open(INFILE,"<$file") or die "Unable to open file: $file\n";
while(<INFILE>) {
&$listsub($file,$_) if /$re/; #$re contains the regex
} #end while
close(INFILE);
} #end DIRLOOP
close(OUTFILE);
}#end sub test_it
##########################################################
sub files_only { #print only the file name, and skip to the next file
print "$_[0]\n";
close(INFILE);
next DIRLOOP;
}#end sub files_only
##########################################################
sub all_lines { #print the filename and the matching line.
print "$_[0]: $_[1]";
}#end sub all_lines
My main question is are there any places I can optimize my code to help it run faster?
Please feel free to criticize!
![[peace] [peace] [peace]](/data/assets/smilies/peace.gif)
Plus, maybe this post can help other people?
Thanks in advance!
Brian