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

时间:2010-02-19 09:57:29

标签: bash shell grep

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

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

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

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

目前,我只能搜索一个关键字。我想搜索存储在 args 数组中的所有关键字。

任何建议都将受到高度赞赏。

谢谢, 基兰

6 个答案:

答案 0 :(得分:7)

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

或者使用shell

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"

答案 1 :(得分:3)

这是一种方式:

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

修改

基于 Pavel 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

答案 2 :(得分:3)

您可以使用一些bash扩展魔法为每个元素添加前缀-e,并将该数组的每个元素作为单独的模式传递。这可以避免一些优先级问题,其中您的模式可能与|的交互不良操作者:

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

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

答案 3 :(得分:1)

命令

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

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

如果我有一种方法可以将数组元素连接成一个字符串,用 sequence 字符(即\|)分隔它们,可以不用perl regexp来完成。

答案 4 :(得分:0)

也许是这样的;

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

未经测试!

答案 5 :(得分:0)

我倾向于对所有内容使用流程替换。与grep的{​​{1}}选项结合使用很方便:

  

从FILE中获取模式,每行一个。

(根据具体情况,您甚至可能希望将其与-f-x结合使用,以产生令人赞叹的效果。)

所以:

-w

我得到:

#! /usr/bin/env bash

t=(8 12 24)

seq 30 | grep -f <(printf '%s\n' "${t[@]}")

我基本上写了一个伪文件,每行包含一个数组项,然后告诉8 12 18 24 28 使用这些行中的每一个作为模式。