我正在寻找一种快速方法来查找包含 2 个或更多模式的文件夹中的所有文件
grep -l -e foo -e bar ./*
或者
rg -l -e foo -e bar
显示同一行中包含“foo”和“bar”或不同行中包含“foo”或“bar”的所有文件,但我只想要在不同行中至少有一个“foo”匹配和一个“bar”匹配的文件。仅包含“foo”匹配或仅包含“bar”匹配的文件将被过滤掉。
我知道我可以链接 grep 调用,但这太慢了。
cha*_*win 13
所以这并不能完美地回答这个问题,但是,这是每次我用谷歌搜索“ripgrep 多个模式”时都会弹出的 StackOverflow 问题。所以我把我的答案留给未来的谷歌人(包括我自己)......
我主要使用 PowerShell 工作,因此这就是我and在 PowerShell 中的 ripgrep 中执行搜索的方式。这将匹配相同的行匹配,这就是为什么它不是一个完美的答案,但它会识别匹配两种模式的文件,并且运行得相对较快:
rg -l 'SecondSearchPattern' (rg -l 'FirstSearchPattern')
Run Code Online (Sandbox Code Playgroud)
解释:
首先,括号运行:rg -l 'FirstSearchPattern',它在所有文件中搜索模式FirstSearchPattern。通过使用-l它仅返回文件路径列表。
通过将其放在(括号中),它首先运行整个命令,然后将命令的结果“splats”到外部rg命令中。
外部rg命令现在像这样运行:
rg -l 'SecondSearchPattern' "file.txt" "directory\file.txt"
是的,它确实将它们放入引号中,因此它处理带有空格的路径。这将搜索所有提供的与模式匹配的文件SecondSearchPattern。因此仅返回与两种模式匹配的文件。
您可以更进一步,添加| Get-Item( | gi) 以返回文件系统对象,并| % FullName获取完整路径。
rg -l 'SecondSearchPattern' (rg -l 'FirstSearchPattern') | gi | % FullName
Run Code Online (Sandbox Code Playgroud)
rg和multiline确实有效,但是它会打印出标准之间的所有内容,有时这没有用。
对于链接搜索的用例(例如html, json等),第一个标准只是缩小文件范围,第二个标准实际上是我正在寻找的,这是一个可能的解决方案:
rg -0 -l crit1 | xargs -0 -I % rg -H crit2 %
Run Code Online (Sandbox Code Playgroud)
另外,我刚刚发现它支持在行和文件ugrep级别使用布尔运算符组合多个条件。这是一件了不起的事情。它比 慢一点,但是它很好地打印了与文件中所有条件匹配的所有行(而不是只显示上面的最后一个条件):rg + xargs
ugrep --files -e crit1 --and -e crit2
Run Code Online (Sandbox Code Playgroud)
如果要搜索多行中出现的两个或多个单词,除了提供/之外,还可以使用ripgrep's 选项。还需要搜索before和before使用运算符:--multiline-dotall-U--multilinefoobarbarfoo|
rg -lU --multiline-dotall 'foo.*bar|bar.*foo' .
Run Code Online (Sandbox Code Playgroud)
对于任意数量的单词,您需要|这些单词的所有排列。为此,我使用一个小的 python 脚本(我称之为rga),它在当前目录(及向下)中搜索包含命令行上给出的所有参数的文件:
#! /opt/util/py310/bin/python
import sys
import subprocess
from itertools import permutations
rgarg = '|'.join(('.*'.join(x) for x in permutations(sys.argv[1:])))
cmd = ['rg', '-lU', '--multiline-dotall', rgarg, '.']
# print(' '.join(cmd))
proc = subprocess.run(cmd, capture_output=True)
sys.stdout.write(proc.stdout.decode('utf-8'))
Run Code Online (Sandbox Code Playgroud)
我已经成功搜索了六个参数,上面的命令行变得很长。可能有办法解决这个问题,方法是将参数保存到文件中并添加-f file_name,但我从未需要/调查过这一点。
$ cat f1
afoot
2bar
$ cat f2
foo bar
$ cat f3
foot
$ cat f4
bar
$ cat f5
barred
123
foo3
$ rg -Ul '(?s)foo.*?\n.*?bar|bar.*?\n.*?foo'
f5
f1
Run Code Online (Sandbox Code Playgroud)
您可以使用-U选项来跨行匹配。该s标志.也将能够匹配换行符。由于您希望匹配跨越不同的行,因此您还需要在搜索词之间匹配换行符。