#!/usr/bin/perl -w # Andgrep - designed for use with TWiki, so only supports -l and -i options, # and is based on egrep. # $Id: andgrep,v 1.2 2001/07/09 13:29:18 rdonkin Exp rdonkin $ # Copyright (C) 2001 Richard Donkin, rdonkin@orchestream.com # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details, published at # http://www.gnu.org/copyleft/gpl.html # Usage: # andgrep [-l] [-i] pattern file ... # # Where # pattern is of the form 'pattern1;pattern2;...', i.e. ';' is used # to indicate matching pattern1 AND pattern2 AND ..., anywhere in the file # For better performance, put most specific matches first, e.g. # # andgrep 'cupcakes;English' *.txt # # The first term cuts down the list of files a great deal, # resulting in fewer files being re-scanned than if the # (presumably more common) term 'English' was used as the first term. # Unlike agrep, any egrep regular expression can be used. # Pick up the options $doListfiles = ""; $doIgnorecase = ""; while ( $ARGV[0] =~ /^-/ ) { if ($ARGV[0] eq "-l") { $doListfiles = "-l"; shift(@ARGV); } elsif ($ARGV[0] eq "-i") { $doIgnorecase = "-i"; shift(@ARGV); } } # Handle the case where -l is not specified, to cover # topicname searching with regular expressions: just do a normal # egrep with no ANDing. if ($doListfiles ne "-l") { $simplePattern = shift(@ARGV); @filenames = @ARGV; $cmd = "egrep $doIgnorecase '$simplePattern' @filenames"; system("$cmd"); exit; } # Split sub-patterns to be ANDed - semicolon indicates AND, as with agrep. $fullPattern = shift(@ARGV); @patterns = split(';', $fullPattern); # open (DEBUG, ">/tmp/debugit"); # Loop through patterns, one egrep per pattern, reducing initial filename # list until only those that match all patterns are present. @filenames = @ARGV; foreach $simplePattern (@patterns) { $cmd = "egrep $doIgnorecase $doListfiles '$simplePattern' @filenames"; # print DEBUG "$cmd\n" ; # print DEBUG "--------\n"; @filenames = ` $cmd `; # print DEBUG "result = @filenames\n"; # Get rid of the \n after every filename chomp(@filenames); } # Only produce output if one or more filenames found if (@filenames) { print join("\n", @filenames) . "\n"; }