2009-12-01 75 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