我有几个文件夹,每个文件夹包含几个.nc
文件。我想循环遍历所有文件夹,并为每个文件夹对cdo
具有相似模式的文件进行一些计算(合并时间)。到目前为止我已经写了以下内容:
for dir in /mnt/meteo_a/africa_cordex/historical/0.44/pr/*/
do
dir=${dir%*/}
echo ${dir##*/}
export dir
cd $dir
pwd
for f in `find . -type f -regex /(.*?\day)/*`
cdo mergetiem io
done
done
每个文件夹中的文件的名称如下:
pr_AFR-44_CNRM-CERFACS-CNRM-CM5_historical_r1i1p1_CLMcom-CCLM4-8-17_v1_day_19500101-19501231.nc
pr_AFR-44_CNRM-CERFACS-CNRM-CM5_historical_r1i1p1_CLMcom-CCLM4-8-17_v1_day_19510101-19551231.nc
pr_AFR-44_ICHEC-EC-EARTH_historical_r12i1p1_CLMcom-CCLM4-8-17_v1_day_19491201-19501231.nc
pr_AFR-44_ICHEC-EC-EARTH_historical_r12i1p1_CLMcom-CCLM4-8-17_v1_day_19510101-19551231.nc
我想对之前具有类似模式的所有文件应用 mergetime CDO 命令_day_
。
我想合并前两个文件和最后两个文件。更具体地说,合并以以下开头的文件
"pr_AFR-44_CNRM-CERFACS-CNRM-CM5_historical_r1i1p1_CLMcom-CCLM4-8-17_v1_"
同样合并以以下开头的文件
"pr_AFR-44_ICHEC-EC-EARTH_historical_r12i1p1_CLMcom-CCLM4-8-17_v1"
合并时间的输出可能类似于:
{pattern}_mergetime.nc
答案1
该脚本片段适用于您的示例文件
for file in *.nc
do
echo "$file"
done | sed 's/_day_.*//' | sort -u | while read -r pattern
do
cdo mergetime "${pattern}"* "${pattern}_mergetime.nc"
done
解释:
- 循环每行
for
打印echo
一个文件名。 - 该
sed
命令删除_day_
所有后续字符。 sort -u
对部分文件名进行排序并删除重复项。while read -r pattern
每行读取一个模式并循环遍历这些模式"${pattern}"*
由 shell 扩展到以该模式开头的所有文件名
for
比循环更好echo
可能是
find . -maxdepth 1 -type f -name '*.nc'
这将打印*.nc
当前目录中匹配的所有文件名,不包含子目录。
您可以将其与所有子目录的循环结合起来,类似于问题中的脚本
for dir in /mnt/meteo_a/africa_cordex/historical/0.44/pr/*/
do
dir=${dir%*/}
echo ${dir##*/}
export dir
pushd $dir
pwd
find . -maxdepth 1 -type f -name '*.nc' | sed 's/_day_.*//' | sort -u | while read -r pattern
do
cdo mergetime "${pattern}"* "${pattern}_mergetime.nc"
done
popd
done
相反,cd
我建议pushd
允许popd
稍后再回去。
您还可以将for
目录上的循环替换为附加的find
find /mnt/meteo_a/africa_cordex/historical/0.44/pr -maxdepth 1 -mindepth 1 -type d | while read dir
do
pushd "$dir"
find . -maxdepth 1 -type f -name '*.nc' | sed 's/_day_.*//' | sort -u | while read -r pattern
do
cdo mergetime "${pattern}"* "${pattern}_mergetime.nc"
done
popd
done