grep 查找多个参数,但按出现顺序输出它们

grep 查找多个参数,但按出现顺序输出它们

我想从输出文件中 grep 出内容。例如abcd

该文件如下所示:

asdf
ab
hgr
cd
ab
asdsda

如果我现在 grep一个abcd一个像

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),而不是基本的grepwithout理解的正则表达式-E(例如,x+会匹配x+with grep,但会匹配一个或多个xes with awk)。

相关内容