如何优化CHELSA气候数据处理的Bash for循环 消除冗余建目录逻辑
高效实现方案
优化核心思路
- 调整循环层级:把原来「外层遍历月份、内层依次处理3个气候变量」的顺序反过来,外层循环只遍历3个气候变量,每个变量仅做1次目录创建,内层循环遍历12个月份执行数据裁剪下载,直接消除33次冗余的mkdir调用
- 解决嵌套思路卡壳的核心问题:针对3个气候变量的源文件路径、输出文件名格式差异,使用Bash关联数组做规则映射,不用为每个变量单独编写完整的gdal_translate命令块,不管路径格式有多少细节差异,只要在数组里写清楚对应规则,循环逻辑就能通用
- 用
mkdir -p替代基础mkdir,增强脚本容错性,避免重复运行时因目录已存在中断流程 - 公共参数抽离为独立变量,后续调整gdal压缩等级、裁剪范围时只需要修改一处
可直接运行的脚本
# 定义公共gdal参数,避免重复书写 GDAL_TRANSLATE_OPTS=(-projwin "$ulx" "$uly" "$lrx" "$lry" -co COMPRESS=DEFLATE -co ZLEVEL=9) # 声明关联数组,存储每个气候变量对应的源URL模板、输出文件名模板 # (需Bash 4.0及以上版本支持关联数组,低版本可改用平行索引数组实现相同逻辑) declare -A SRC_URL=( [tmin]='/vsicurl/https://os.zhdk.cloud.switch.ch/envicloud/chelsa/chelsa_V1/climatologies/tmin/CHELSA_tmin10_%s_1979-2013_V1.2_land.tif' [prec]='/vsicurl/https://os.zhdk.cloud.switch.ch/envicloud/chelsa/chelsa_V1/climatologies/prec/CHELSA_prec_%s_V1.2_land.tif' [tmax]='/vsicurl/https://os.zhdk.cloud.switch.ch/envicloud/chelsa/chelsa_V1/climatologies/tmax/CHELSA_tmax10_%s_1979-2013_V1.2_land.tif' ) declare -A OUT_NAME=( [tmin]='CHELSA_tmin10_%s_1979-2013_V1.2_land_crop.tif' [prec]='CHELSA_prec_%s_V1.2_land_crop.tif' [tmax]='CHELSA_tmax10_%s_1979-2013_V1.2_land_crop.tif' ) # 外层循环:遍历所有气候变量,仅执行1次目录创建 for var in tmin prec tmax; do mkdir -p "$var" cd "$var" || exit 1 # 内层循环:遍历12个月份,执行裁剪操作 for MM in 01 02 03 04 05 06 07 08 09 10 11 12; do # 用printf把月份值填充到模板里,生成完整路径 printf -v src_path "${SRC_URL[$var]}" "$MM" printf -v out_path "${OUT_NAME[$var]}" "$MM" gdal_translate "${GDAL_TRANSLATE_OPTS[@]}" "$src_path" "$out_path" done cd .. || exit 1 done
优化效果说明
- 目录创建次数从原脚本的36次(12个月*3个变量)降低到3次,完全消除重复的磁盘IO操作
- 去掉了所有重复的gdal_translate命令块,后续如果要新增气候变量(比如辐射、风速数据),只需要在关联数组里新增1行对应的URL、文件名规则,不用重复编写完整的命令
- 增加
cd操作的容错判断,避免目录异常时脚本进入错误路径继续执行,防止文件存错位置 - 脚本重复运行时不会因为已有目录直接报错,可根据需要额外增加文件存在判断逻辑,跳过已完成的裁剪步骤
内容的提问来源于stack exchange,提问作者Common_Codin
相关产品推荐
相关产品推荐

