From owner-freebsd-questions@FreeBSD.ORG Wed Jun 27 16:25:26 2012 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9BAC5106564A for ; Wed, 27 Jun 2012 16:25:26 +0000 (UTC) (envelope-from bmettee@pchotshots.com) Received: from mail.pchotshots.com (mail.pchotshots.com [12.172.123.237]) by mx1.freebsd.org (Postfix) with ESMTP id 5A44A8FC0C for ; Wed, 27 Jun 2012 16:25:26 +0000 (UTC) Received: (qmail 10182 invoked by uid 89); 27 Jun 2012 16:18:45 -0000 Received: from unknown (HELO ?12.172.123.228?) (bmettee@pchotshots.com@12.172.123.228) by mail.pchotshots.com with ESMTPA; 27 Jun 2012 16:18:45 -0000 Message-ID: <4FEB325B.5010802@pchotshots.com> Date: Wed, 27 Jun 2012 12:18:35 -0400 From: Brad Mettee User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20120614 Thunderbird/13.0.1 MIME-Version: 1.0 To: Aleksandr Miroslav References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-questions@freebsd.org Subject: Re: shell scripting: grepping multiple patterns, logically ANDed X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Jun 2012 16:25:26 -0000 On 6/27/2012 11:25 AM, Tim Daneliuk wrote: > On 06/27/2012 09:25 AM, Aleksandr Miroslav wrote: >> hello, >> >> I'm not sure if this is the right forum for this question, but here >> goes. >> >> I have the following in a shell script: >> >> >> #!/bin/sh >> >> if [ "$#" -eq "0" ]; then >> find /foo >> fi >> if [ "$#" -eq "1" ]; then >> find /foo | grep -i $1 >> fi >> if [ "$#" -eq "2" ]; then >> find /foo | grep -i $1 | grep -i $2 >> fi >> if [ "$#" -eq "3" ]; then >> find /foo | grep -i $1 | grep -i $2 | grep -i $3 >> fi >> >> Is there an easier/shorter way to do this? If there are 15 arguments >> supplied on the command line, I don't necessarily want to build 15 if >> statements. >> >> Thanks in advance for your answers. > > The following solution relies on the fact that you can include multiple > patterns for grep to match with the '-e' argument: > > > #!/bin/sh > > PATTERNS=`echo " $*" | sed s/\ /\ -e\ /g` > > find /foo | grep $PATTERNS > > Notice that when constructing the $PATTERNS string out of the command > line > args, you have to quote them with a prepended space character. That's > because > the subsequent 'sed' substitution needs to find a space *before* each > argument > which it then replaces with "-e ". This will build a multi-grep string for any number of arguments (within reason), functionally a boolean AND search: #!/bin/sh final_cmd="find /foo" while [ $# -gt 0 ] do final_cmd="$final_cmd | grep -i $1" shift done $final_cmd May need quoting changes, but it worked on this sample, with this result: cmdline: ./testshift "1" 1 2 3 4 5 result: "find /foo | grep -i 1 | grep -i 1 | grep -i 2 | grep -i 3 | grep -i 4 | grep -i 5" HTH Brad