首页 > 解决方案 > 提高 bash 脚本的性能

问题描述

我正在循环处理数十万个 CSV 文件以从中生成更多文件。要求是从每个文件中提取前 1 个月、3 个月、1 个月、1 年和 2 年的数据并从中生成新文件。

我编写了以下脚本,它完成了工作,但速度非常慢。这个脚本需要经常运行,这让我的生活变得很麻烦。请问有没有更好的方法来实现我所追求的结果或可能提高这个脚本的性能?

for k in *.csv; do
    sed -n '/'"$(date -d "2 year ago" '+%Y-%m')"'/,$p' ${k} > temp_data_store/${k}.2years.csv
    sed -n '/'"$(date -d "1 year ago" '+%Y-%m')"'/,$p' ${k} > temp_data_store/${k}.1year.csv
    sed -n '/'"$(date -d "6 month ago" '+%Y-%m')"'/,$p' ${k} > temp_data_store/${k}.6months.csv
    sed -n '/'"$(date -d "3 month ago" '+%Y-%m')"'/,$p' ${k} > temp_data_store/${k}.3months.csv
    sed -n '/'"$(date -d "1 month ago" '+%Y-%m')"'/,$p' ${k} > temp_data_store/${k}.1month.csv
done

标签: bashshell

解决方案


您阅读每个 CSV 五次。最好只读取每个 CSV 一次。

您多次提取相同的数据。除了一个部分之外的所有部分都是其他部分的子集。

  • 2 年前是 1 年前、6 个月前、3 个月前和 1 个月前的子集。
  • 1 年前是 6 个月前、3 个月前和 1 个月前的子集。
  • 6 个月前是 3 个月前和 1 个月前的子集。
  • 3 个月前是 1 个月前的子集。

这意味着“2years.csv”中的每一行也在“1year.csv”中。所以从“1year.csv”中提取“2years.csv”就足够了。您可以使用 级联不同的搜索tee

以下假设您的文件内容按时间顺序排列。(我稍微简化了引用)

sed -n "/$(date -d '1 month ago' '+%Y-%m')/,\$p" "${k}" |
tee temp_data_store/${k}.1month.csv |
sed -n "/$(date -d '3 month ago' '+%Y-%m')/,\$p" |
tee temp_data_store/${k}.3months.csv |
sed -n "/$(date -d '6 month ago' '+%Y-%m')/,\$p" |
tee temp_data_store/${k}.6months.csv |
sed -n "/$(date -d '1 year ago' '+%Y-%m')/,\$p" |
tee temp_data_store/${k}.1year.csv |
sed -n "/$(date -d '2 year ago' '+%Y-%m')/,\$p" > temp_data_store/${k}.2years.csv

推荐阅读