Is it possible to do a grep with keywords stored i

2019-03-27 20:56发布

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

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 args array.

Any suggestion would be highly appreciated.

Thanks, Kiran

标签: bash shell grep
6条回答
beautiful°
2楼-- · 2019-03-27 21:36

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's suggestion:

( 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:

Even better than the version using IFS:

printf -v keys "%s\\|" "${args[@]}"; grep "${keys}" file_name
查看更多
一夜七次
3楼-- · 2019-03-27 21:42

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:

$ 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.

查看更多
对你真心纯属浪费
4楼-- · 2019-03-27 21:44
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"
查看更多
神经病院院长
5楼-- · 2019-03-27 21:44

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|word3 that matches any word from the alternatives given (in perl mode).

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

查看更多
太酷不给撩
6楼-- · 2019-03-27 21:51

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!

查看更多
一夜七次
7楼-- · 2019-03-27 21:58

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

Obtain patterns from FILE, one per line.

(Depending on the context, you might even want to combine that with -x or -w for awesome effects.)

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 grep to use each of these lines as a pattern.

查看更多
登录 后发表回答