regex - 递归列出包含 m of n 正则表达式的文件
问题描述
我有一个包含很多文件的目录。我有n
搜索模式,想列出所有匹配m
的文件。
示例:从下面的文件中,列出至少包含、和中两个的文件。str1
str2
str3
str4
$ ls -l dir/
total 16
-rw-r--r--. 1 me me 10 Jun 22 14:22 a
-rw-r--r--. 1 me me 5 Jun 22 14:22 b
-rw-r--r--. 1 me me 10 Jun 22 14:22 c
-rw-r--r--. 1 me me 9 Jun 22 14:22 d
-rw-r--r--. 1 me me 10 Jun 22 14:22 e
$ cat dir/a
str1
str2
$ cat dir/b
str2
$ cat dir/c
str2
str3
$ cat dir/d
str
str4
$ cat dir/e
str2
str4
我设法通过一个相当丑陋的for
循环来实现这一点,该循环为每个文件find
生成n
grep
进程,这显然是超级低效的,并且在包含大量文件的目录上会花费很长时间:
for f in $(find dir/ -type f); do
c=0
grep -qs 'str1' $f && let c++
grep -qs 'str2' $f && let c++
grep -qs 'str3' $f && let c++
grep -qs 'str4' $f && let c++
[[ $c -ge 2 ]] && echo $f
done
我很确定我可以以更好的方式实现这一目标,但我不知道如何解决它。根据我从手册页(即 on-e
和-m
)中了解到的情况,单独使用这是不可能的grep
。
什么是正确的工具?这可能awk
吗?
奖励:通过使用find
我可以更精确地定义要搜索的文件(即-prune
某些子目录或仅搜索带有 的文件-iname '*.txt'
),我也想用其他解决方案来做。
更新
下面是一些关于不同实现的性能的统计数据。
find
+awk
(来自这个答案的脚本)
real 0m0,006s
user 0m0,002s
sys 0m0,004s
python
(我是python
菜鸟,请告知是否可以优化):
import os
patterns = []
patterns = ["str1", "str2", "str3", "str4"]
for root, dirs, files in os.walk("dir"):
for file in files:
c = int(0)
filepath = os.path.join(root, file)
with open(filepath, 'r') as input:
for pattern in patterns:
for line in input:
if pattern in line:
c += 1
break
if ( c >= 2 ):
print(filepath)
real 0m0,025s
user 0m0,019s
sys 0m0,006s
c++
(来自这个答案的脚本)
real 0m0,002s
user 0m0,001s
sys 0m0,001s
解决方案
$ cat reg.txt
str1
str2
str3
str4
$ cat prog.awk
# reads regexps from the first input file
# parameterized by `m'
# requires gawk or mawk for `nextfile'
FNR == NR {
reg[NR] = $0
next
}
FNR == 1 {
for (i in reg)
tst[i]
cnt = 0
}
{
for (i in tst) {
if ($0 ~ reg[i]) {
if (++cnt == m) {
print FILENAME
nextfile
}
delete tst[i]
}
}
}
$ find dir -type f -exec awk -v m=2 -f prog.awk reg.txt {} +
dir/a
dir/c
推荐阅读
- mongodb - 来自多个 mongo 实例的 MongoDB 导出器指标
- linux-kernel - 每个进程并行运行时是否有自己的虚拟地址空间?
- python - 拒绝只包含空格的字符串
- php - 允许每个用户单击一次元素
- c - 将使用 Windows 编译器的 C 交叉编译的 make-system 从 Cygwin 移动到 WSL2
- javascript - 在异步函数内的 for 循环中等待会产生奇怪的结果
- fastapi - FastAPI 动态生成 Sub-API
- javascript - 如何使用 ErrorBoundary 收集错误组件的状态
- apache-kafka - 可扩展的竞争消费者选项
- c# - 如果我们使用 ExcelDataReader 包,如何提高 Excel 文件的读取速度?