Re: shell scripting: grepping multiple patterns, logically ANDed
On Wed, 27 Jun 2012 10:25:46 -0400, Aleksandr Miroslav alexmiros...@gmail.com 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. The solutions proposed so far are ok, if you really *have* to stick to a shell script. For safer regexp pattern construction I'd probably convert the script to some language that makes it less easy to shoot yourself in the foot because you missed a quote or because you happened to choose ' as the quoting character and one of the patterns includes it too. I'd write this sort of logic in python, constructing 'regexp' patterns on the go from the command-line arguments: #!/usr/bin/env python import sys import re if __name__ == '__main__': pattern = '^.*$'# Match everything by default matcher = None if len(sys.argv) 1: pattern = ( r'^.*(' + '|'.join(map(lambda part: r'' + part, sys.argv[1:])) + ').*$') try: # print 'pattern = %s' % pattern matcher = re.compile(pattern) except: sys.stderr.write('invalid pattern: %s' % pattern) sys.exit(1) for line in sys.stdin.readlines(): # print '# line = %s, match = %s' % ( # line.rstrip(), matcher.match(line)) if matcher.match(line): line = line.rstrip() print '%s' % line This should be able to match even patterns with quotes embedded, e.g.: 0630 22:21 kobe:~$ ./foo.py it's dark When it's dark, the world is normally a quieter place When it's dark ^D When it's dark, When it's dark 0630 22:22 kobe:~$ ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
shell scripting: grepping multiple patterns, logically ANDed
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. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: shell scripting: grepping multiple patterns, logically ANDed
On 06/27/2012 10: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 . Whoops, I just realized that I ORed them and you want them ANDed. Hmmm ... must go think on that... ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: shell scripting: grepping multiple patterns, logically ANDed
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 . --- Tim Daneliuk ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: shell scripting: grepping multiple patterns, logically ANDed
On 06/27/2012 10:33 AM, Tim Daneliuk wrote: On 06/27/2012 10: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 . Whoops, I just realized that I ORed them and you want them ANDed. Hmmm ... must go think on that... OK, here is an ANDing version: #!/bin/sh PATMATCH=`echo $* | sed s/' '/' | grep '/g` eval find ./ $PATMATCH -- --- Tim Daneliuk ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: shell scripting: grepping multiple patterns, logically ANDed
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 ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org