2010-02-19 71 views
6

是否有可能使用存储在数组中的关键字执行grep。是否可以使用存储在数组中的关键字执行grep?

以下是可能的代码片段...请更正

args=("key1" "key2" "key3") 

cat file_name |while read line 
echo $line | grep -q -w ${args[c]} 
done 

此刻,我可以只搜索一个关键字。我想搜索存储在参数列表数组中的所有关键字。

任何建议将不胜感激。

感谢, 基兰

+1

尽管不是真正的解决方案,但cat用于连接文件,如果只有一个文件,请使用输入指令: while read line echo $ line | grep -q -w $ {args [c]} done Residuum 2010-02-19 10:13:20

+0

非常感谢..我已经习惯了通过看到其他例子..没有意识到它.. 感谢吨 – Kiran 2010-02-19 10:29:48

回答

5
args=("key1" "key2" "key3") 
pat=$(echo ${args[@]}|tr " " "|") 
grep -Eow "$pat" file 

或者与外壳

args=("key1" "key2" "key3") 
while read -r line 
do 
    for i in ${args[@]} 
    do 
     case "$line" in 
      *"$i"*) echo "found: $line";; 
     esac 
    done 
done <"file" 
+0

非常感谢..它的工作。 :) – Kiran 2010-02-19 10:31:50

0

或许是这样的;

cat file_name |while read line 
for arg in ${args[@]} 
do 
echo $line | grep -q -w $arg} 
done 
done 

未经测试!

+0

嗯,我需要搜索两个关键字同时像$ {args [*]}或egrep与多个关键字。 有什么想法? – Kiran 2010-02-19 10:25:05

1

命令

(IFS="|" ; grep --perl-regexp "${args[*]}") <file_name 

搜索数组中的每一个关键字的文件。它通过构造正则表达式word1|word2|word3来实现,该正则表达式匹配给定选项(以perl模式)中的任何单词。

如果我没有加入数组元素转换为字符串的方式,用字符(即,\|),也可能是没有Perl的正则表达式完成的序列界定他们。

+0

在我的系统上,它是单数:'--perl-regexp'。此外,无用的使用'猫'。 – 2010-02-19 10:31:02

+0

@丹尼斯,谢谢,修正。顺便说一句,我可以争论猫。 – 2010-02-19 10:37:25

+0

'(IFS ... grep ... file_name)' - 不需要重定向。 '--perl-regexp'中的'grep'确实有's'吗? – 2010-02-19 13:40:50

3

这是一种方式:

args=("key1" "key2" "key3") 
keys=${args[@]/%/\\|}  # result: key1\| key2\| key3\| 
keys=${keys// }   # result: key1\|key2\|key3\| 
grep "${keys}" file_name 

编辑:

基于帕维尔Shved的建议:

(IFS="|"; keys="${args[*]}"; keys="${keys//|/\\|}"; grep "${keys}" file_name) 

第一个版本作为一个班轮:

keys=${args[@]/%/\\|}; keys=${keys// }; grep "${keys}" file_name 

EDIT2:

甚至比更好的版本使用IFS

printf -v keys "%s\\|" "${args[@]}"; grep "${keys}" file_name 
+0

你能解释你的解决方案的工作原理吗?我被困在理解%模式参数[@] /%/ \\ |中的目的 – Sharad 2016-05-25 10:37:58

+0

@Sharad:在Shell Parameter Expansion中查看] Bash手册](https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion)。在我的示例'keys = $ {args [@] /%/ \\ |}''中的赋值语句用于替换('/')数组每个元素的末尾('%')('args [@]'' )用('/')反斜杠和一个管道('\\ |')。所以它添加了这些字符,因为“结束”(一个'%'后跟没有其他字符匹配)就是这样 - 在这种情况下,在“替换”期间不会删除字符。 – 2016-05-25 13:25:38

2

你可以使用一些bash的扩张魔法前缀每个元素都带-e并传递阵列的每个元素y作为一个单独的模式。这可能会避免一些优先级问题,其中您的模式可能会与|严重交互运营商:

$ grep ${args[@]/#/-e } file_name 

这样做的缺点是您的模式中不能有任何空格,因为它会将参数拆分为grep。你不能在上面展开引号,否则你会得到“-e pattern”作为grep的一个参数。

相关问题