You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

大日志文件PO编号查询脚本优化请求:缩短2.45小时执行时长

优化大日志文件中多PO编号统计的执行效率

兄弟,你的脚本慢得离谱的核心原因一眼就能看出来——你循环调用了11k+次grep,每次都要把500-600MB的日志文件从头到尾读一遍,磁盘IO的开销直接拉满,不慢才怪!咱们换个思路:只把日志文件读一次,就能完成所有PO的统计,效率能提升几十甚至上百倍。

方案1:用awk一次性处理(最推荐,性能最优)

awk可以一次性把所有PO编号加载到内存,然后遍历一次日志文件完成统计,全程只需要读一次日志和一次PO列表,把磁盘IO开销降到最低。

直接用这个脚本替换你的循环:

awk -v po_list="po_numbers" '
BEGIN {
    # 先把所有PO编号加载到关联数组,初始计数设为0
    while ((getline po < po_list) > 0) {
        count[po] = 0
    }
    close(po_list)
}
# 遍历日志每一行,匹配到PO_NUMBER字段就提取编号并计数
/PO_NUMBER=/ {
    split($0, parts, "PO_NUMBER=")
    po = parts[2]
    # 只统计在我们目标列表里的PO
    if (po in count) {
        count[po]++
    }
}
# 处理完所有日志后,输出结果到指定文件
END {
    for (po in count) {
        print po "-->" count[po] >> "list3"
        if (count[po] == 0) {
            print po >> "po_to_server"
        }
    }
}
' Test.log

这个脚本的执行时间应该能从几小时直接压缩到几分钟甚至几十秒,完全不是一个量级的提升。

方案2:用grep的-f选项批量匹配(更简洁)

如果你对awk不太熟悉,也可以用grep的批量匹配功能,同样只读一次日志:

# 第一步:批量匹配所有目标PO的行,提取PO编号后统计出现次数
grep -o "PO_NUMBER=\([^[:space:]]*\)" Test.log | grep -f <(sed 's/^/PO_NUMBER=/' po_numbers) | cut -d'=' -f2 | sort | uniq -c > temp_counts

# 第二步:和原PO列表对比,生成最终的统计文件和未找到的PO列表
awk 'NR==FNR {count[$2]=$1; next} {
    print $0 "-->" (count[$0] ? count[$0] : 0) >> "list3"
    if (!count[$0]) print $0 >> "po_to_server"
}' temp_counts po_numbers

# 清理临时文件
rm temp_counts

这个方案的性能比awk稍逊一筹,但比你的原脚本快太多,而且写法更贴近你熟悉的grep命令。

原脚本的性能瓶颈拆解

最后给你理清楚为什么原脚本这么慢:

  • 磁盘IO爆炸:每次循环都要重新打开、读取、关闭500MB的日志文件,11k次循环就是11k次磁盘IO,这是最慢的操作
  • 进程创建开销:每次调用grep都会创建一个新进程,11k次进程创建的开销累积起来也相当可观

内容的提问来源于stack exchange,提问作者Rasesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:10:47