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

提升bash脚本性能:批量处理CSV文件提取多时间范围数据

脚本优化方案

原脚本性能瓶颈

  • 单文件重复读取:每个CSV被sed遍历5次,磁盘IO开销直接放大5倍,数十万文件场景下这是最大性能损耗点
  • 重复计算时间阈值:循环内每次执行5次date命令,完全可以提前全局计算一次
  • 无提前终止逻辑:sed会遍历整个文件,哪怕目标数据已经全部输出

核心优化实现

用awk单次遍历单个CSV即可同时生成5个目标文件,同时新增提前终止逻辑,避免无效读取:

# 提前创建输出目录,避免报错
mkdir -p temp_data_store

# 全局预计算所有时间阈值,仅执行一次
d2y=$(date -d "2 year ago" '+%Y-%m')
d1y=$(date -d "1 year ago" '+%Y-%m')
d6m=$(date -d "6 month ago" '+%Y-%m')
d3m=$(date -d "3 month ago" '+%Y-%m')
d1m=$(date -d "1 month ago" '+%Y-%m')

# 循环处理所有CSV,单文件仅遍历一次
for k in *.csv; do
  awk -v d2y="$d2y" -v d1y="$d1y" -v d6m="$d6m" -v d3m="$d3m" -v d1m="$d1m" \
      -v outdir="temp_data_store/" -v fname="$k" '
  BEGIN {
    f2y = 0; f1y = 0; f6m = 0; f3m = 0; f1m = 0
    out2y = outdir fname ".2years.csv"
    out1y = outdir fname ".1year.csv"
    out6m = outdir fname ".6months.csv"
    out3m = outdir fname ".3months.csv"
    out1m = outdir fname ".1month.csv"
  }
  # 表头统一写入所有输出文件
  NR == 1 {
    print $0 > out2y; print $0 > out1y; print $0 > out6m; print $0 > out3m; print $0 > out1m
    next
  }
  {
    # 提取当前行的YYYY-MM格式日期,日期在行首用substr($0,1,7),日期在第一列直接写cur=$1即可
    cur = substr($0, 1, 7)
    # 匹配到对应时间阈值后开启对应文件的写入标记
    if (!f2y && cur >= d2y) f2y = 1
    if (f2y) print $0 > out2y

    if (!f1y && cur >= d1y) f1y = 1
    if (f1y) print $0 > out1y

    if (!f6m && cur >= d6m) f6m = 1
    if (f6m) print $0 > out6m

    if (!f3m && cur >= d3m) f3m = 1
    if (f3m) print $0 > out3m

    if (!f1m && cur >= d1m) f1m = 1
    if (f1m) print $0 > out1m

    # 所有标记都开启后说明所有时间段的数据已经全部输出,直接终止当前文件读取
    if (f2y && f1y && f6m && f3m && f1m) exit
  }' "$k"
done

进阶并行优化

如果服务器CPU核心充足,可以用GNU Parallel并行处理文件,进一步压缩耗时:

# 并行数-j可根据CPU核心数调整,建议设为核心数的1~2倍
ls *.csv | parallel -j 16 '
  awk -v d2y='"$d2y"' -v d1y='"$d1y"' -v d6m='"$d6m"' -v d3m='"$d3m"' -v d1m='"$d1m"' \
      -v outdir="temp_data_store/" -v fname="{}" '\''
  BEGIN {
    f2y = 0; f1y = 0; f6m = 0; f3m = 0; f1m = 0
    out2y = outdir fname ".2years.csv"
    out1y = outdir fname ".1year.csv"
    out6m = outdir fname ".6months.csv"
    out3m = outdir fname ".3months.csv"
    out1m = outdir fname ".1month.csv"
  }
  NR == 1 {
    print $0 > out2y; print $0 > out1y; print $0 > out6m; print $0 > out3m; print $0 > out1m
    next
  }
  {
    cur = substr($0, 1, 7)
    if (!f2y && cur >= d2y) f2y = 1
    if (f2y) print $0 > out2y
    if (!f1y && cur >= d1y) f1y = 1
    if (f1y) print $0 > out1y
    if (!f6m && cur >= d6m) f6m = 1
    if (f6m) print $0 > out6m
    if (!f3m && cur >= d3m) f3m = 1
    if (f3m) print $0 > out3m
    if (!f1m && cur >= d1m) f1m = 1
    if (f1m) print $0 > out1m
    if (f2y && f1y && f6m && f3m && f1m) exit
  }'\'' {}
'

预期性能提升

仅替换为awk单遍历逻辑,性能即可达到原脚本的5~10倍,加上并行优化后,耗时可随核心数线性下降,完全满足高频运行需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:24:05