5k行文件批量grep搜索提速及多类型文件搜索配置求助
Bash脚本优化及文件类型搜索方案
一、原脚本的性能瓶颈分析
原脚本核心性能问题:
- 循环内每次执行
>> result2.txt,反复打开、写入、关闭文件,产生大量IO开销 - 每一行都重新扫描整个目录(5000次重复遍历),这是最大的性能浪费
- 使用
cat filtered.txt | while多创建了一个不必要的进程
二、脚本优化方案
1. 减少文件IO操作
将整个循环的输出一次性重定向到结果文件,避免频繁的文件打开/关闭:
#!/bin/bash while read line; do echo "$line" grep -lr "$line" /somepath/* done < filtered.txt > result2.txt
同时去掉多余的cat进程,改用< filtered.txt直接给while提供输入。
2. 避免重复扫描目录
提前缓存需要搜索的文件列表,避免5000次重复遍历目录:
#!/bin/bash # 提前缓存目标路径下所有要搜索的文件 target_files=$(find /somepath -type f \( -name "*.txt" -o -name "*.zip" \)) while read line; do echo "$line" # 直接在缓存的文件列表中搜索 grep -lr "$line" $target_files 2>/dev/null done < filtered.txt > result2.txt
2>/dev/null用来屏蔽zip文件无法被grep直接读取的错误,后续会单独处理zip文件。
三、仅搜索*.txt和*.zip文件的实现
由于grep无法直接读取zip压缩内容,需要结合grep处理txt文件、zgrep处理zip文件,同时解决zgrep不能递归的问题:
优化后的完整脚本
#!/bin/bash # 提前缓存所有zip文件路径,避免循环内重复执行find zip_files=$(find /somepath -type f -name "*.zip") while read line; do echo "$line" # 递归搜索所有txt文件 grep -lr "$line" --include="*.txt" /somepath # 批量搜索缓存的zip文件 zgrep -l "$line" $zip_files done < filtered.txt > result2.txt
关键说明
grep -r --include="*.txt":支持递归搜索,仅匹配txt文件find + zgrep:用find递归找出所有zip文件,缓存后传给zgrep批量处理,规避zgrep无法递归的问题- 若zip文件过多导致参数溢出,可改用以下方式分批处理:
find /somepath -type f -name "*.zip" -exec zgrep -l "$line" {} +
四、极致优化:一次性处理所有模式
如果不需要严格保持“先输出模式,再输出匹配文件”的顺序,可以用grep -f一次性加载所有模式,大幅减少进程创建次数:
#!/bin/bash # 处理txt文件并整理格式 grep -H -f filtered.txt --include="*.txt" -r /somepath | awk -F: '{print $2; print $1}' # 处理zip文件并整理格式 find /somepath -type f -name "*.zip" -exec zgrep -H -f filtered.txt {} + | awk -F: '{print $2; print $1}' # 合并结果并去重(按需选择) sort -u > result2.txt
这种方式将5000次循环的搜索合并为2次批量搜索,性能提升显著。
内容的提问来源于stack exchange,提问作者localhost01
相关产品推荐
相关产品推荐

