2009-12-01 69 views
0

從本質上講,我想的東西,功能類似於線:查找包含所有關鍵字bash腳本

cat file | grep -i keyword1 | grep -i keyword2 | grep -i keyword3 

我怎樣才能做到這一點與一個bash腳本,它的關鍵字參數可變長度的名單?該腳本應該對包含所有關鍵字的行進行不區分大小寫的匹配。

+0

你問我們怎麼做到這一點的最好辦法是什麼? – 2009-12-01 22:04:51

+0

是的。什麼是在一個bash腳本中使用可變數量關鍵字的最優雅/有效的方法? – Siou 2009-12-01 22:10:28

+0

失去那隻無用的貓 – ghostdog74 2009-12-01 23:34:47

回答

3

以此爲腳本

 
#! /bin/bash 
awk -v IGNORECASE=1 -f <(
    P=; for k; do [ -z "$P" ] && P="/$k/" || P="$P&&/$k/"; done 
    echo "$P{print}" 
) 

並調用它作爲

 
script.sh keyword1 keyword2 keyword3 < file 
1

我不知道這是否是有效的,而且我認爲這是醜陋的,也可能有一些實用程序這一點,但:

#!/bin/bash 

unset keywords matchlist 
keywords=("[email protected]") 

for kw in "${keywords[@]}"; do 
matchlist="$matchlist /$kw/ &&" 
done 

matchlist="${matchlist% &&}" 

# awk "$matchlist { print; }" < <(tr '[:upper:]' '[:lower:]' <file) 
awk "$matchlist { print; }" file 

是的,它需要一定的魯棒性有關特殊字符和東東。這只是爲了展示這個想法。

+0

謝謝,這就是它的要義。但是,我將如何使關鍵字匹配不區分大小寫(如grep -i)? – Siou 2009-12-01 23:03:01

+0

你抓住了我!我認爲GNU awk具有類似IGNORECASE變量的東西,但我不確定。 如果它是一個選項,則可以在讀入時小寫輸入文件並僅使用小寫關鍵字:awk ... <<(tr'[:upper:]''[:lower:]' TheBonsai 2009-12-02 05:15:20

1

這給一試:

shopt -s nocasematch 
keywords="keyword1|keyword2|keyword3" 
while read line; do [[ $line =~ $keywords ]] && echo $line; done < file 

編輯

下面是所有關鍵字存在測試版本,不是任何:

keywords=(keyword1 keyword2 keyword3) # or keywords=("[email protected]") 
qty=${#keywords[@]} 
while read line 
do 
    count=0 
    for keyword in "${keywords[@]}" 
    do 
     [[ "$line" =~ $keyword ]] && ((count++)) 
    done 
    if ((count == qty)) 
    then 
     echo $line 
    fi 
done < textlines 
+0

謝謝,我以前沒有使用過shopt - 總是很高興學到新的東西。這給出了一個不區分大小寫的匹配,但匹配包含任何關鍵字的行。我只想匹配包含所有關鍵字的行。 – Siou 2009-12-01 23:17:14

0

你可以使用bash 4.0 ++

shopt -s nocasematch 
while read -r line 
do 
    case "$line" in 
     *keyword1*) f=1;;& 
     *keyword2*) g=1;;& 
     *keyword3*) 
      [ "$f" -eq 1 ] && [ "$g" -eq 1 ] && echo $line;; 
    esac 
done < "file" 
shopt -u nocasematch 

或呆子

gawk '/keyword/&&/keyword2/&&/keyword3/' file 
+0

這需要Bash 4 – 2009-12-02 05:38:08

0

發現了一種使用grep做到這一點。

[email protected] 
MATCH_EXPR="cat file" 
for keyword in ${KEYWORDS}; 
do 
    MATCH_EXPR="${MATCH_EXPR} | grep -i ${keyword}" 
done 
eval ${MATCH_EXPR} 
0

我會做它用Perl。

爲了找到包含它們中的至少一個所有行:

perl -ne'print if /(keyword1|keyword2|keyword3)/i' file 

對於查找包含所有的人都行:

perl -ne'print if /keyword1/i && /keyword2/i && /keyword3/i' file