Reputation: 353
I need to grep multiple strings, but i don't know the exact number of strings. My code is :
s2=( $(echo $1 | awk -F"," '{ for (i=1; i<=NF ; i++) {print $i} }') )
for pattern in "${s2[@]}"; do
ssh -q host tail -f /some/path |
grep -w -i --line-buffered "$pattern" > some_file 2>/dev/null &
done
now, the code is not doing what it's supposed to do. For example if i run ./script s1,s2,s3,s4,.....
it prints all lines that contain s1,s2,s3....
The script is supposed to do something like grep "$s1" | grep "$s2" | grep "$s3" ....
Upvotes: 0
Views: 896
Reputation: 241931
grep
doesn't have an option to match all of a set of patterns. So the best solution is to use another tool, such as awk
(or your choice of scripting languages, but awk will work fine).
Note, however, that awk
and grep
have subtly different regular expression implementations. It's not clear from the question whether the target strings are literal strings or regular expression patterns, and if the latter, what the expectations are. However, since the argument comes delimited with commas, I'm assuming that the pieces are simple strings and should not be interpreted as patterns.
If you want the strings to be interpreted as patterns, you can change index
to match
in the following little program:
ssh -q host tail -f /some/path |
awk -v STRINGS="$1" -v IGNORECASE=1 \
'BEGIN{split(STRINGS,strings,/,/)}
{for(i in strings)if(!index($0,strings[i]))next}
{print;fflush()}'
Note:
IGNORECASE
is only available in gnu awk; in (most) other implementations, it will do nothing. It seems that is what you want, based on the fact that you used -i
in your grep invocation.
fflush()
is also an extension, although it works with both gawk
and mawk
. In Posix awk
, fflush
requires an argument; if you were using Posix awk
, you'd be better off printing to stderr
.
Upvotes: 1
Reputation: 2169
test.sh:
#!/bin/bash -x
a=" $@"
grep ${a// / -e } .bashrc
it works that way:
$ ./test.sh 1 2 3
+ a=' 1 2 3'
+ grep -e 1 -e 2 -e 3 .bashrc
(here is lots of text that fits all the arguments)
Upvotes: 0
Reputation: 15350
You can use extended grep
egrep "$s1|$s2|$s3" fileName
If you don't know how many pattern you need to grep, but you have all of them in an array called s
, you can use
egrep $(sed 's/ /|/g' <<< "${s[@]}") fileName
This creates a herestring
with all elements of the array, sed replaces the field separator of bash (space) with |
and if we feed that to egrep we grep all strings that are in the array s
.
Upvotes: 0