Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jun 2012 12:18:35 -0400
From:      Brad Mettee <bmettee@pchotshots.com>
To:        Aleksandr Miroslav <alexmiroslav@gmail.com>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: shell scripting: grepping multiple patterns, logically ANDed
Message-ID:  <4FEB325B.5010802@pchotshots.com>
In-Reply-To: <CACcSE1zwRcU_VQ16A2wiG4yWk4RBRykTXBono3xspw97zhDs7w@mail.gmail.com>
References:  <CACcSE1zwRcU_VQ16A2wiG4yWk4RBRykTXBono3xspw97zhDs7w@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4FEB325B.5010802>