如何在bash中grep多个变量

时间:2013-11-21 00:59:13

标签: bash grep

我需要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”....

3 个答案:

答案 0 :(得分:1)

grep没有匹配一组模式的所有的选项。因此,最好的解决方案是使用其他工具,例如awk(或您选择的脚本语言,但awk可以正常工作)。

但请注意,awkgrep具有略微不同的正则表达式实现。从目标字符串是文字字符串还是正则表达式模式的问题来看,目前尚不清楚,如果是后者,那么期望是什么。但是,由于参数以逗号分隔,我假设这些片段是简单的字符串,并且应该被解释为模式。

如果您希望将字符串解释为模式,可以在以下小程序中将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()}'

注意:

  1. IGNORECASE仅适用于gnu awk;在(大多数)其他实现中,它什么都不做。根据您在grep调用中使用-i的事实,这似乎就是您想要的。

  2. fflush()也是一个扩展程序,但它适用于gawkmawk。在Posix awk中,fflush需要一个参数;如果您使用Posix awk,最好打印到stderr

答案 1 :(得分:0)

您可以使用扩展的

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

如果您不知道grep需要多少个模式,但是您将所有模式都放在名为s的数组中,则可以使用

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

这会创建一个herestring,其中包含数组的所有元素,会将{b}(空格)的字段分隔符替换为|,如果我们将其提供给我们数组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)