bash 是否可以对存储在数组中的关键字进行 grep?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2295361/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 21:41:50  来源:igfitidea点击:

Is it possible to do a grep with keywords stored in the array?

bashshellgrep

提问by Kiran

Is it possible to do a grep with keywords stored in the array.

是否可以对存储在数组中的关键字进行 grep。

Here is the possible code snippet... Please correct it

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

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

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

At the moment, I can search for only one keyword. I would like to search for all the keywords which is stored in argsarray.

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

Any suggestion would be highly appreciated.

任何建议将不胜感激。

Thanks, Kiran

谢谢,基兰

回答by ghostdog74

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

Or with the 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"

回答by camh

You can use some bash expansion magic to prefix each element with -e and pass each element of the array as a separate pattern. This may avoid some precedence issues where your patterns may interact badly with the | operator:

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

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

The downside to this is that you cannot have any spaces in your patterns because that will split the arguments to grep. You cannot put quotes around the above expansion, otherwise you get "-e pattern" as a single argument to grep.

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

回答by Paused until further notice.

This is one way:

这是一种方式:

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

Edit:

编辑:

Based on Pavel Shved'ssuggestion:

基于Pavel Shved 的建议:

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

The first version as a one-liner:

作为单行的第一个版本:

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

Edit2:

编辑2:

Even better than the version using IFS:

甚至比使用的版本更好IFS

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

回答by P Shved

The command

命令

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

searches the file for each keyword in an array. It does so by constructing regular expression word1|word2|word3that matches any word from the alternatives given (in perl mode).

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

If I there is a way to join array elements into a string, delimiting them with sequenceof characters (namely, \|), it could be done without perl regexp.

如果我有一种方法可以将数组元素连接到一个字符串中,用字符序列(即,\|)分隔它们,那么它可以在没有 perl regexp 的情况下完成。

回答by Alice M.

I tend to use process substitution for everything. It's convenient when combined with grep's -foption:

我倾向于对一切都使用过程替换。与grep's-f选项结合使用时很方便:

Obtain patterns from FILE, one per line.

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

(Depending on the context, you might even want to combine that with -xor -wfor awesome effects.)

(根据上下文,你甚至可能要结合起来,与-x-w为真棒效果。)

So:

所以:

#! /usr/bin/env bash

t=(8 12 24)

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

and I get:

我得到:

8
12
18
24
28

I basically write a pseudo-file with one item of the array per line, and then tell grepto use each of these lines as a pattern.

我基本上写了一个伪文件,每行包含一个数组项,然后告诉grep将这些行中的每一行用作模式。

回答by matpol

perhaps something like this;

也许是这样的;

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

not tested!

未测试!