Bash grep -P 带有文件中的正则表达式列表
Bash grep -P with a list of regexes from a file
问题:必须针对大量 PCRE 正则表达式对数百个目录中的数十万个文件进行测试,以对文件进行计数和分类,并确定哪些正则表达式更可行、更具包容性。
我对单个正则表达式测试的方法:
find unsorted_test/. -type f -print0 |
xargs -0 grep -Pazo '(?P<message>User activity exceeds.*?\:\s+(?P<user>.*?))\s' |
tr -d '[=11=]0' |
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
的 "the too many arguments" 错误
grep -Pazo
负责繁重的工作 -P
用于 PCRE 正则表达式 -a
用于确保文件被读取为文本 -z -o
只是因为它不适用于我拥有的文件库
tr -d '[=18=]0'
是确保输出不是二进制的
fgrep -a
是只获取文件名
的行
sed
是为了抵消 grep 相互附加尾随行的好习惯(基本上删除文件路径前一行中的所有内容)
cut -d: -f1
仅切断文件路径
wc -l
统计匹配的filelist的结果大小
结果是一个包含 10k+ 行的文件,如下所示:unsorted/./2020.03.02/68091ec4-cf04-4843-a4b2-95420756cd53
这正是我最终想要的。
显然这不是很好,但是对于用木棍和泥土制成的东西来说效果很好。我在这里的主要 objective 是测试概念和正则表达式,不计入进一步缩放或任何东西,真的。
所以,由于 grep -P
不支持 -f
参数,我尝试使用 while read
循环:
(while read regexline ;
do echo "$regexline" ;
find unsorted_test/. -type f -print0 |
xargs -0 grep -Pazo "$regexline" |
tr -d '[=12=]0' |
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 中的引号、循环类型等进行了试验。没有。
非常感谢任何有关当前代码的帮助或关于如何执行此操作的建议。
谢谢。
P.S。是的,我试过 pcregrep,但它 returns 即使在单个模式上也是零匹配。不知道为什么。
你可以做到这不可能慢:
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 '[=10=]0' | 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 '[=11=]0' | 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
。 read
的 -d ''
选项是 bash 语法。
- 仅在竖线后有空格、制表符和注释的行将被忽略。您可以将命令放在不同的行中。
- 使用
grep -F
而不是弃用的 fgrep
。
问题:必须针对大量 PCRE 正则表达式对数百个目录中的数十万个文件进行测试,以对文件进行计数和分类,并确定哪些正则表达式更可行、更具包容性。
我对单个正则表达式测试的方法:
find unsorted_test/. -type f -print0 |
xargs -0 grep -Pazo '(?P<message>User activity exceeds.*?\:\s+(?P<user>.*?))\s' |
tr -d '[=11=]0' |
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 '[=18=]0'
是确保输出不是二进制的
fgrep -a
是只获取文件名
sed
是为了抵消 grep 相互附加尾随行的好习惯(基本上删除文件路径前一行中的所有内容)
cut -d: -f1
仅切断文件路径
wc -l
统计匹配的filelist的结果大小
结果是一个包含 10k+ 行的文件,如下所示:unsorted/./2020.03.02/68091ec4-cf04-4843-a4b2-95420756cd53
这正是我最终想要的。
显然这不是很好,但是对于用木棍和泥土制成的东西来说效果很好。我在这里的主要 objective 是测试概念和正则表达式,不计入进一步缩放或任何东西,真的。
所以,由于 grep -P
不支持 -f
参数,我尝试使用 while read
循环:
(while read regexline ;
do echo "$regexline" ;
find unsorted_test/. -type f -print0 |
xargs -0 grep -Pazo "$regexline" |
tr -d '[=12=]0' |
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 中的引号、循环类型等进行了试验。没有。
非常感谢任何有关当前代码的帮助或关于如何执行此操作的建议。 谢谢。
P.S。是的,我试过 pcregrep,但它 returns 即使在单个模式上也是零匹配。不知道为什么。
你可以做到这不可能慢:
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 '[=10=]0' | 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 '[=11=]0' | 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
。read
的-d ''
选项是 bash 语法。 - 仅在竖线后有空格、制表符和注释的行将被忽略。您可以将命令放在不同的行中。
- 使用
grep -F
而不是弃用的fgrep
。