我想从输出文件中 grep 出内容。例如ab
和cd
。
该文件如下所示:
asdf
ab
hgr
cd
ab
asdsda
如果我现在 grep一个ab
又cd
一个像
for i in $@
do
grep $i file
done
我明白了
ab
ab
cd
我想要的是
ab
cd
ab
有优雅的解决方案吗?
答案1
您得到此结果是因为循环首先执行grep ab file
并返回ab
第一次迭代中出现的所有情况,然后在此循环执行grep cd file
并返回cd
中出现的所有情况file
。
你不需要for
循环。尝试这个:
grep -e "^ab$" -e "^cd$" file
或者使用-x
选项仅选择那些与整行完全匹配的匹配项(从man grep
,thx 到善行难陀):
grep -x -e "ab" -e "cd" file
输出将是:
ab
cd
ab
或者(假设 GNUgrep
或兼容 as\|
不是标准 BRE 运算符):
grep "^\(ab\|cd\)$" file
与 GNU 相同sed
:
sed '/^\(ab\|cd\)$/!d' file
答案2
使用:
IFS='
' # to join "$*" with newline
grep -e "$*" < file
在grep -- "$patterns"
or中grep -e "$patterns"
, 的每一行$patterns
都是一个要查找的模式(ORed)。 (如果其中的任何模式"$@"
本身是多行的,您可能需要记住这一点)
在 POSIX shell 中,"$*"
是位置参数与 的第一个字符的串联$IFS
。
-x
如果您希望模式完全匹配行x
(而不是行内的子字符串),请添加该选项。
ab
请注意,与 和匹配的行cd
(因此没有-x
)将仅打印一次,这将是与多遍方法的另一个区别。如果您希望为每个匹配模式打印一次,您可以使用awk
:
awk '
BEGIN {
for (i = 1; i < ARGC; i++) pattern[ARGV[i]]
ARGC = 1
}
{for (p in pattern) if ($0 ~ p) print}' "$@" < file
但请注意,awk
模式是扩展的正则表达式(如 in grep -E
),而不是基本的grep
without理解的正则表达式-E
(例如,x+
会匹配x+
with grep
,但会匹配一个或多个x
es with awk
)。