Bash脚本通过占位符循环遍历netCDF文件并使用cdo命令

时间:2017-12-06 02:55:21

标签: bash for-loop netcdf cdo

我想遍历40个netCDF文件。变量PRECC有20个文件,变量PRECL("modelmember001.PRECC.192001-200512.nc", "modelmember002.PRECC.192001-200512.nc", ... ,"modelmember020.PRECC.192001-200512.nc"和变量PRECL分别有20个文件。

我需要使用循环执行多个cdo(气候数据运算符)命令(添加PRECC和PRECL文件,并将时间序列从1920-2005更改为1955-2005)。

这是我使用的代码:

  datadir="path_to_mydatat"
    workdir="path_to_folder_for_newfiles"
    members="{001 .. 020}"

    for model in $members
    do

    echo 'working with model' ${model}

    echo cdo -s add ${datadir}/modelmember${members}.PRECC.192001-200512.nc${datadir}/modelmember${members}.PRECL.192001-200512.nc ${workdir}/modelmember${members}PRECT.192001-200512.nc
    # echo cdo -s selyear,1955/2005 ${workdir}/modelmember${members}.PRECT.192001-200512.nc ${workdir}/modelmember${members}.PRECT.195501-200512.nc

最终我需要20个名为

的文件
"modelmember001.PRECT.195501-200512.nc", "modelmember002.PRECT.195501-200512.nc", ... , "modelmember020.PRECT.195501-200512.nc"

这是我运行代码时得到的(故意在cdo行前面有一个“echo”):

$./cdo_add.sh

{001 .. 020}

working with model {001

cdo -s add /path_to_mydatat/modelmember{001 .. 020}.PRECC.192001-200512.nc         /path_to_mydatat/modelmember{001 .. 020}.PRECL.192001-200512.nc  /path_to_folder_for_newfiles/modelmember{001 .. 020}.PRECT.192001-200512.nc

working with model ..

cdo -s add /path_to_mydatat/modelmember{001 .. 020}.PRECC.192001-200512.nc /path_to_mydatat/modelmember{001 .. 020}.PRECL.192001-200512.nc /path_to_folder_for_newfiles/modelmember{001 .. 020}.PRECT.192001-200512.nc

working with model 020}

cdo -s add /path_to_mydatat/modelmember{001 .. 020}.PRECC.192001-200512.nc /path_to_mydatat/modelmember{001 .. 020}.PRECL.192001-200512.nc /path_to_folder_for_newfiles/modelmember{001 .. 020}.PRECT.192001-200512.nc

我的代码似乎没有遍历成员。我使用占位符“成员”的方式有问题,但我无法弄清楚如何解决它。 有没有人有建议? 干杯!

1 个答案:

答案 0 :(得分:1)

您的代码似乎没有循环,因为您无法为变量分配大括号扩展,并期望在for循环中替换它时展开。以下内容将文字字符串"{001 .. 020}"保存到变量members,例如

members="{001 .. 020}"

members中使用for model in $members时,会发生正常的分词,因为它只是一个字符串,您使用001循环一次,然后使用..循环,最后使用020 - 不是来自001, 002, 003, ... 020的预期序列。 (数字与..之间不应有空格 - 但仍然不允许您在变量中使用扩展)

要正确使用扩展,请完全删除members变量并在循环中使用{001..020},例如

for model in {001..020}   ## (notice NO space between 001 and ..)

示例:

$ for m in {001..020}; do echo $m; done
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020

这将允许您在model中循环播放序列。

根据评论中的对话,我知道您有40个文件前缀为modelmemberXXX(其中XXX001-020),后跟.PRECC*或{{1您希望协调将匹配对提供给cdo命令的(每个20个文件)。虽然首选的方法是循环一个匹配的glob,例如.PRECL*,您也可以使用大括号扩展方法,例如

for i in modelmember*.PRECC*; do

(注意for i in {001..020} do a=$(echo modelmember${i}.PRECC*) b=$(echo modelmember${i}.PRECL*) if [ -e "$a" ] && [ -f "$b" ] then printf "%s\n%s\n\n" "$a" "$b" fi done 测试只是确保该对中的两个文件都存在,然后再继续执行命令([ -e "$a" ] && [ -f "$b" ]此处))

示例输出

printf

您只需在循环中使用modelmember001.PRECC.192001-200512.nc modelmember001.PRECL.192001-200512.nc modelmember002.PRECC.192001-200512.nc modelmember002.PRECL.192001-200512.nc modelmember003.PRECC.192001-200512.nc modelmember003.PRECL.192001-200512.nc ... modelmember020.PRECC.192001-200512.nc modelmember020.PRECL.192001-200512.nc $a以及$b。 (如评论中所述,您需要更改为包含文件的目录,或者在文件名前加cdo_cmd

首选方式

不是使用大括号扩展,而是优先循环一组(path/to/the/filesPRECC),验证另一组,然后执行命令,例如

PRECL

(相同的输出)