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

优化基于grep、awk、cut的大文件邮件数字统计脚本性能

大日志文件下的唯一邮件数字统计优化方案

需求说明

从包含以下格式的日志文件中,统计每个数字对应的唯一邮件数量(需过滤同一邮件的重复记录):

2024-05-08 11:02:58,731 INFO o.a.j.a.J.Some check: Closest Day: Wed, New quantity for email0987@yahoo.com is: 1

期望输出示例:

1 - 6575 emails
2 - 333 emails

现有bash脚本处理几百MB的大文件时速度极慢,需要性能优化。

现有脚本的性能瓶颈

原脚本存在以下低效点:

  • 多次调用外部工具(grep/cut/rev/awk)并通过管道传递数据,产生大量进程切换开销
  • 将过滤后的所有数据读入变量再通过while read循环处理,内存占用高且bash循环本身速度缓慢
  • 循环内再次调用echo/cut等外部工具,进一步放大进程开销

优化方案:单Awk脚本完成所有操作

直接用Awk一次性完成日志过滤、去重、统计,避免多进程和bash循环的开销,这是处理大文本文件最高效的方式之一。

优化后的脚本

#!/bin/bash
input_file="$1"

awk '/Closest Day:/ {
    # 直接提取邮件和数字:邮件是倒数第3个字段,数字是倒数第1个字段
    email = $(NF-2)
    number = $NF
    # 用"邮件-数字"作为复合键去重,确保同一邮件对应同一数字只统计一次
    if (!seen[email, number]++) {
        count[number]++
    }
}
END {
    # 输出统计结果
    for (num in count) {
        printf "%d - %d emails\n", num, count[num]
    }
}' "$input_file"

优化点说明

  • 单进程处理:全程仅启动一个Awk进程,彻底避免多管道和外部工具的进程切换开销
  • 内存高效去重:用复合键email, number记录已出现的组合,确保同一邮件对应同一数字只计数一次
  • 原生字段提取:Awk原生支持字段索引,无需cut/rev等工具拆分字符串
  • 无中间数据拷贝:直接读取原文件处理,无需将中间结果存入变量再二次处理

额外性能建议

  • 如果日志文件是压缩格式,直接用zcat/bzcat配合Awk处理,避免先解压再读取:
    zcat "$input_file.gz" | awk '...'
    
  • 若需要按数字排序输出,可将结果管道到sort -n:
    awk '...' "$input_file" | sort -n
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:40:19