2013-11-21 66 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)