我想遍历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
我的代码似乎没有遍历成员。我使用占位符“成员”的方式有问题,但我无法弄清楚如何解决它。 有没有人有建议? 干杯!
答案 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
(其中XXX
为001-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/files
或PRECC
),验证另一组,然后执行命令,例如
PRECL
(相同的输出)