2013-11-21 40 views
0

我需要grep多个字符串,但我不知道字符串的确切数量。 我的代码是:如何在bash中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” ......

回答

1

grep没有一个选项来与之匹配一组模式的所有。所以最好的解决方案是使用另一个工具,比如awk(或者你选择的脚本语言,但awk可以正常工作)。

但是请注意,awkgrep具有细微差别的正则表达式实现。从目标字符串是字面字符串还是正则表达式模式以及后者的期望是什么这个问题来看,并不清楚。但是,由于参数以逗号分隔,因此我假定这些部分是简单的字符串,并且应该将而不是解释为模式。

如果你想字符串被解释为模式,你可以在下面的小程序更改indexmatch

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()}' 

注:

  1. IGNORECASE仅在GNU AWK提供;在(大多数)其他实现中,它什么都不会做。这似乎是你想要的,基于你在你的grep调用中使用了-i这一事实。

  2. fflush()也是一个扩展,虽然它与gawkmawk一起使用。 Posix awkfflush需要一个参数;如果您使用Posix awk,则最好打印到stderr

+0

完美的作品,谢谢你哦! – user2864207

+0

我没有使用fflush。林不知道我明白它的作用,但即时通讯的尾部输出到一个文件,并且一切似乎工作正常。 – user2864207

+0

@ user2864207:'fflush()'和grep选项'--line-buffered'做同样的事情;也就是说,它会强制每个输出行立即写入,而不是被缓存。 – rici

0

您可以使用扩展

egrep "$s1|$s2|$s3" fileName 

如果你不知道你需要多少模式到grep,但是你所有的人都在一个数组叫s ,你可以使用

egrep $(sed 's/ /|/g' <<< "${s[@]}") fileName 

这将创建数组的所有元素herestring|取代庆典(空间)的字段分隔符,如果我们养活,为我们数组中的所有字符串s

+0

我不能,因为我不知道我应该grep多少个字符串 – user2864207

+0

我编辑了我的答案。你能检查一下它是否适合你? – pfnuesel

+0

我输入了以下命令ssh -q host tail -f some/path | egrep -w -i -line-buffered“$(sed's// |/g'<<<”$ {s2 [@]}“)”>文件 它给了我一个snytax错误 – user2864207

0

test.sh:

#!/bin/bash -x 
a=" [email protected]" 
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)