一次匹配文件中的所有模式

一次匹配文件中的所有模式

我有 2 个文件:argstext.例如:

args: [包含脚本的参数]

life
happy
horse

文本:

The horse has a happy life.
Life is fun.
Kids are happy.

我需要一个命令来打印text包含 中所有模式的行args。在这种情况下:The horse has a happy life.

答案1

git grep

这是使用的语法git grep使用布尔表达式组合多个模式:

git grep -e "life" --and -e "happy" --and -e "horse"

上面的命令将立即打印匹配所有模式的行。

如果文件不受版本控制,请添加--no-index参数。

搜索当前目录中不受 Git 管理的文件。

检查man git-grep寻求帮助。

grep

通常grep使用-f参数将打印至少具有一种模式的行,例如

grep -f args.txt file.txt

在你的情况下它不会起作用。

因此,要同时打印匹配所有模式的行,您可以尝试以下命令:

while read n text; do [ $n -eq $(wc -l < args.txt) ] && echo $text; done < <(while read patt; do grep "$patt" text.txt; done < args.txt | sort | uniq -c)

解释:

  1. 内部循环将打印与使用文件中的模式列表while中的至少一个模式匹配的所有行。text.txtargs.txt
  2. 然后对该列表进行排序 ( sort) 并计算出现次数 ( uniq -c)。
  3. while循环将仅打印出现次数与其中模式数相同的行args.txt(即 3)。

另一种方法是删除与至少一个模式不匹配的所有行。

以下是使用 Ex/Vim 编辑器就地更改文件的解决方案:

while read patt; do ex +"v/$patt/d" -scwq text.txt; done < args.txt

注意:这将从文件本身中删除不需要的行。

这是较短的版本,仅在屏幕上打印结果:

ex $(xargs -I% printf "+v/%/d " < args.txt) +%p -scq! text.txt

更改+%p -scq!-scwq将其就地保存到文件中。


这是通过定义 shell 别名的解决方案:

alias grep-all="</dev/stdin $(xargs printf '|grep "%s"' < args.txt)"

使用示例:

grep-all file.txt

有关的:

答案2

使用awk

~$ cat textlist.txt | awk '/life/ && /happy/ && /horse/ { print; }'
The horse has a happy life

textlist.txt 是您给出的句子列表。

答案3

您可以使用agrep来应用手术。不幸的是它不能应用文件中的模式列表,因此您必须首先将其扩展为命令参数。

patterns=$(sed 's/;/\\;/' <args | tr '\n' ';' | sed 's/;$//')
agrep "$patterns" text

生成模式列表的修改用分号将它们连接在一起。但是,我们不能在列表末尾有分号,这样它就会被删除,并且任何已经包含分号的模式都必须对该字符进行转义,这样它就不会被视为操作员。用于echo "$patterns"查看args文件是如何转换的。

答案4

也许这不是最有效的方法,但它似乎有效:

# for a in $(cat args); do regex="$regex | grep '$a'"; done
# eval cat text "$regex"
The horse has a happy life.

相关内容