我需要grep多个字符串,但我不知道字符串的确切数量。 我的代码是:
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
现在,代码没有做它应该做的事情。例如,如果我运行./script s1,s2,s3,s4,.....
它会打印包含s1,s2,s3 ....
的所有行脚本应该像grep“$ s1”|那样做grep“$ s2”| grep“$ s3”....
答案 0 :(得分:1)
grep
没有匹配一组模式的所有的选项。因此,最好的解决方案是使用其他工具,例如awk
(或您选择的脚本语言,但awk可以正常工作)。
但请注意,awk
和grep
具有略微不同的正则表达式实现。从目标字符串是文字字符串还是正则表达式模式的问题来看,目前尚不清楚,如果是后者,那么期望是什么。但是,由于参数以逗号分隔,我假设这些片段是简单的字符串,并且不应该被解释为模式。
如果您希望将字符串解释为模式,可以在以下小程序中将index
更改为match
:
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()}'
注意:
IGNORECASE
仅适用于gnu awk;在(大多数)其他实现中,它什么都不做。根据您在grep调用中使用-i
的事实,这似乎就是您想要的。
fflush()
也是一个扩展程序,但它适用于gawk
和mawk
。在Posix awk
中,fflush
需要一个参数;如果您使用Posix awk
,最好打印到stderr
。
答案 1 :(得分:0)
您可以使用扩展的grep
egrep "$s1|$s2|$s3" fileName
如果您不知道grep需要多少个模式,但是您将所有模式都放在名为s
的数组中,则可以使用
egrep $(sed 's/ /|/g' <<< "${s[@]}") fileName
这会创建一个herestring
,其中包含数组的所有元素,sed会将{b}(空格)的字段分隔符替换为|
,如果我们将其提供给egrep我们grep数组s
中的所有字符串。
答案 2 :(得分:0)
test.sh:
#!/bin/bash -x
a=" $@"
grep ${a// / -e } .bashrc
它的工作原理如下:
$ ./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)