#!/usr/bin/env perl ############################################################################################### # This script was written for www.philforhumanity.com. # If you have any questions, issues, or enhancement requests, please contact us via the website. # Use this script at your own risk. ############################################################################################### # regrep version 1.2 $|=1; # set output buffering to off $[=0; # set array base to 0 $,=" "; # set output field separator $\="\n"; # set output record separator use Getopt::Long; use File::Basename; #use File::which; my ($list,$edit,$verbose,$nocase,$help,$debug,$pattern); my $editor = "kate"; # Get arguments GetOptions ( 'list' => \$list, 'edit' => \$edit, 'verbose' => \$verbose, 'nocase' => \$nocase, 'help' => \$help, 'pattern=s' => \$pattern, 'debug' => \$debug ); # If "-help" is the only argument, then print the usage and exit. if ($help == 1) { &usage; exit; }; # Check the number of arguments, and exit with usage if no arguments my $number_of_arguments = scalar(@ARGV); &usage("ERROR: Incorrect number of arguments.") if (scalar(@ARGV)<1); # If "-nocase" argument is used, then see flag to "-i" for grep, otherwise set flag to nothing. my $nocaseflag = (defined $nocase ? '-i' : ''); #if no file pattern is specified, default to * $pattern = $pattern || '*'; # Define query word my $grep_query = $ARGV[0]; # If more than one argument, then collect the paths to search in my @paths_to_search = ("."); # Default is the current directory if ($number_of_arguments > 1) { # Remove first argument, since it is not a path and we collected that data already. shift @ARGV; # Save paths to a meaningful variable name, and overwrite default value @paths_to_search = @ARGV; } # Query each path for files only my @list_of_files = (); my $path; foreach $path (@paths_to_search) { @list_of_files = (@list_of_files, `find $path -type f -name '$pattern' -print`); } my $file_found; `file .`; # Since Git Bash does not have the file command, test if it exists. if ($?) { $file_found = 0; # Not found } else { $file_found = 1; # Found } # For each file found, find which files are text files and then grep only text files my $file; my $find_output; my $found = 0; my @grep_output; my $line; my @foundfiles; my $matchcount=0; chomp @list_of_files; foreach $file (@list_of_files) { #skip editor backup files, or zip files next if ($file =~ /(~|\.bak|\.zip|\.gz|\.msi|\.doc|\.xls)$/); # Debug line # print "file=$file"; if ($file_found == 1) { @grep_output = `file "$file"`; $find_output = @grep_output[0]; if ($find_output !~ /text/) { next; } } # Grep for data (-n is for line numbers) @grep_output = `grep -n $nocaseflag $grep_query "$file"`; # Was fgrep # Output data if grep found something if (@grep_output) { chomp(@grep_output); if ($verbose) { print "=================================================================="; print "File: $file"; } push(@foundfiles,$file); $matchcount += scalar(@grep_output); foreach $line (@grep_output) { print $line if ($verbose); } $found = 1; } } # Print ending delimiter if anything was found if ($found == 1) { my $matchfiles = scalar(@foundfiles); print "==================================================================" if ($verbose); print qq{$matchcount matches in $matchfiles files}; #if the --list option was specified, display a list of all the matching files if ($list) { print qq{Matched files:}; foreach (@foundfiles) { print " $_"; } } if ($edit) { `$editor @foundfiles`; } } sub usage { my $message = shift; print qq{\n$message} if ($message); my $script = basename($0); print qq{ USAGE: $script [path1] [path2] ... [options] options: -verbose - display the matched lines for each file searched. -list - list the files that have matching text. -edit - open the matching files in an editor. -nocase - performs a case insensitive search. -pattern=STR - only searches files that have filenames containing a string of user's choice. The default path is the current directory. Spaces must be escaped to be included in the search string. Files ending in '~', '.zip' or '.gz' are automatically ignored. examples: $script 'Time\\ Clock' --list (searches files for the string "Time Clock" and displays a list of files that have matching text) $script Groucho --edit (searches files for the string "Groucho" and opens the files in an editor) $script Groucho --edit --nocase (searches files for the string "Groucho" (case insensitive) and opens the files in an editor) $script Harpo --verbose (searches files for the string "Harpo" and displays all the matches to the screen) $script -pattern=*txt* TODAY (searches all files that have "txt" in their filenames for the string "TODAY") }; exit 1; }#sub # Exit exit 0;