bash - Bash grep -P 使用文件中的正则表达式列表
问题描述
问题:必须针对多个 PCRE 正则表达式对数百个目录中的数十万个文件进行测试,以对文件进行计数和分类,并确定哪个正则表达式更可行和更具包容性。
我对单个正则表达式测试的方法:
find unsorted_test/. -type f -print0 |
xargs -0 grep -Pazo '(?P<message>User activity exceeds.*?\:\s+(?P<user>.*?))\s' |
tr -d '\000' |
fgrep -a unsorted_test |
sed 's/^.*unsorted/unsorted/' |
cut -d: -f1 > matched_files_unsorted_test000.txt ;
wc -l matched_files_unsorted_test000.txt
find | xargs
允许回避 grep 的“参数过多”错误
grep -Pazo
-P
是为 PCRE 正则表达式做繁重的工作-a
是为了确保文件被读取为文本并且-z -o
仅仅是因为它不适用于我拥有的文件库
tr -d '\000'
是确保输出不是二进制的
fgrep -a
是只获取带有文件名的行
sed
是为了抵消 grep 相互附加尾随行的令人敬畏的习惯(基本上删除文件路径之前一行中的所有内容)
cut -d: -f1
仅切断文件路径
wc -l
计算匹配文件列表的结果大小
结果是一个包含 10k+ 行的文件,如下所示:unsorted/./2020.03.02/68091ec4-cf04-4843-a4b2-95420756cd53
这就是我最终想要的。
显然这不是很好,但这适用于用棍子和泥土制成的东西。我的主要目标是测试概念和正则表达式,而不是计算进一步扩展或任何东西,真的。
所以,由于grep -P
不支持-f
参数,我尝试使用while read
循环:
(while read regexline ;
do echo "$regexline" ;
find unsorted_test/. -type f -print0 |
xargs -0 grep -Pazo "$regexline" |
tr -d '\000' |
fgrep -a unsorted_test |
sed 's/^.*unsorted/unsorted/' |
cut -d: -f1 > matched_files_unsorted_test000.txt ;
wc -l matched_files_unsorted_test000.txt |
sed 's/^ *//' ;
done) < regex_1.txt
正如您可以想象的那样 - 它非常失败:所有内容都为零匹配。
我已经尝试过 grep 中的引号、循环类型等。什么都没有。
非常感谢对当前代码的任何帮助或有关如何执行此操作的建议。谢谢你。
PS 是的,我尝试过 pcregrep,但即使在单个模式上它也会返回零匹配项。不知道为什么。
解决方案
你可以这样做,这将是不可能的慢:
find unsorted_test/. -type f -print0 |
while IFS= read -d '' -r file; do
while IFS= read -r regexline; do
grep -Pazo "$regexline" "$file"
done < regex_1.txt
done |
tr -d '\000' | fgrep -a unsorted_test... blablabla
或者对于每一行:
find unsorted_test/. -type f -print0 |
while IFS= read -d '' -r file; do
while IFS= read -r line; do
while IFS= read -r regexline; do
if grep -Pazo "$regexline" <<<"$line"; then
break
fi
done < regex_1.txt
done |
tr -d '\000' | fgrep -a unsorted_test... blablabl
或者也许与 xargs。
但我相信只需将文件中的正则表达式加入|
:
find unsorted_test/. -type f -print0 |
{
regex=$(< regex_1.txt paste -sd '|')
# or maybe with braces
# regex=$(< regex_1.txt sed 's/.*/(&)/' | paste -sd '|')
xargs -0 grep -Pazo "$regex"
} |
....
笔记:
- 要从文件中读取行,请使用
IFS= read -r line
.-d ''
选项read
是 bash 语法。 - 仅在管道之后带有空格、制表符和注释的行将被忽略。您可以将命令放在单独的行上。
- 使用
grep -F
而不是弃用fgrep
。
推荐阅读
- android-studio - Android Studio 在 Ubuntu 中启动视图解析问题
- amazon-web-services - 如何在 CloudFormation 脚本中将 AmazonEC2RoleforSSM 附加到 ec2 实例
- sqlite - 从 SQLite 表中检索所有行需要多长时间?
- azure - Kubernetes:连接到 Azure SQL
- android - 当列表的各个项目使用Retrofit和Gson的格式不同时,如何解析json列表?
- python - 如何在 SQLAlchemy 和 MySQL 中舍入一个数字?
- ios - 如何在swift中更改除弹出视图外的总屏幕背景颜色
- google-cloud-platform - 是否可以更改 gcloud sdk 的 oauth 应用程序?
- python - Python pandas df使用正则表达式重命名索引
- c++ - C ++ 17中数组索引范围的并行for循环