0

我想循环浏览 40 个 netCDF 文件。有 20 个带有变量的PRECC文件和 20 个带有变量PRECL("modelmember001.PRECC.192001-200512.nc", "modelmember002.PRECC.192001-200512.nc", ... ,"modelmember020.PRECC.192001-200512.nc"和 for的文件PRECL)。

我需要使用循环执行多个 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

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

4

1 回答 1

2

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

members="{001 .. 020}"

当您使用membersinfor model in $members时,会发生正常的分词,因为它只是一个字符串,并且您使用 循环一次001,然后使用循环,..最后使用循环020——而不是预期的序列 from 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(where XXXis 001-020) 为前缀的文件,后跟.PRECC*.PRECL*(每个 20 个文件)您想要协调将匹配对馈送到 cdo 命令。虽然首选方法是遍历一个匹配的 glob,例如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/files

首选方式

而不是使用大括号扩展,可能更喜欢循环一组(PRECCPRECL),验证另一个存在,然后执行命令,例如

for i in modelmember*.PRECC* 
do
    b="${i/PRECC/PRECL}"
    if [ -e "$i" ] && [ -f "$b" ]
    then
        printf "%s\n%s\n\n" "$i" "$b"
    fi
done

(相同的输出)

于 2017-12-06T03:40:17.250 回答