是否可以使用存储在数组中的关键字来执行grep。
以下是可能的代码段...请更正
args=("key1" "key2" "key3")
cat file_name |while read line
echo $line | grep -q -w ${args[c]}
done
目前,我只能搜索一个关键字。我想搜索存储在 args 数组中的所有关键字。
任何建议都将受到高度赞赏。
谢谢, 基兰
答案 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
使用这些行中的每一个作为模式。