rjs*_*ing 1 regex unix shell performance grep
此shell脚本用于从$2包含模式的数据中提取数据行$line.
$line使用正则表达式[A-Z0-9.-]+@[A-Z0-9.-]+(简单的电子邮件匹配)构造,在文件中形成行$1.
#! /bin/sh
clear
for line in `cat "$1" | grep -i -o -E "[A-Z0-9.-]+@[A-Z0-9.-]+"`
do
echo `cat "$2" | grep -m 1 "\b$line\b"`
done
Run Code Online (Sandbox Code Playgroud)
文件$1有短行数据(<100个字符),包含大约.50k线(约1-1.5 MB).
文件$2的文本行稍长(> 80到<200),并且有2M +行(约200MB).
运行的台式机具有足够的RAM(6 Gig)和具有2-4个内核的Xenon处理器.
是否有任何快速修复以提高性能,因为目前需要1-2小时才能完全运行(并输出到另一个文件).
注意:我对所有建议持开放态度,但我们不能复杂地重写整个系统等.此外,数据来自第三方,并且易于随机格式化.
快速建议:
避免无用的使用cat和更改cat X | grep Y到grep Y X.
您可以grep通过管道输出来处理输出,而不是使用反引号.使用反引号需要先grep完成后才能启动第二个grep.
从而:
grep -i -o -E "[A-Z0-9.-]+@[A-Z0-9.-]+" "$1" | while read line; do
grep -m 1 "\b$line\b" "$2"
done
Run Code Online (Sandbox Code Playgroud)
下一步:
$2重复处理.很大.您可以保存所有模式,然后对文件执行单个grep.sed.替换循环.不再重复grep:
grep -i -o -E "[A-Z0-9.-]+@[A-Z0-9.-]+" "$1" | sed -E 's/^|$/\\1/g' > patterns
grep -f patterns "$2"
Run Code Online (Sandbox Code Playgroud)
最后,使用一些bash幻想(参见man bash→流程替换),我们可以抛弃临时文件,并在一个长行中执行此操作:
grep -f <(grep -i -o -E "[A-Z0-9.-]+@[A-Z0-9.-]+" "$1" | sed -E 's/^|$/\\b/g') "$2"
Run Code Online (Sandbox Code Playgroud)
除非你有很多模式grep -f用完内存和barf,否则这很好.如果发生这种情况,您需要批量运行它.讨厌,但可行:
grep -i -o -E "[A-Z0-9.-]+@[A-Z0-9.-]+" "$1" | sed -E 's/^|$/\\1/g' > patterns
while [ -s patterns ]; do
grep -f <(head -n 100 patterns) "$2"
sed -e '1,100d' -i patterns
done
Run Code Online (Sandbox Code Playgroud)
那将一次处理100个模式.它可以立即做的越少,你的第二个文件所需的传递次数就越少.