複数のフォルダを繰り返して、bashで同様のパターンを持つファイルを計算します。

複数のフォルダを繰り返して、bashで同様のパターンを持つファイルを計算します。

複数のフォルダがあり、各フォルダには複数の.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_

最初の2つのファイルと最後の2つのファイルをマージしたいと思います。具体的には、次から始まるファイルをマージします。

"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

説明する:

  • ループは1行に1つのファイル名をfor印刷します。echo
  • このsedコマンドは、_day_その後のすべての文字を削除します。
  • sort -u部分的なファイル名を並べ替え、重複したファイルを削除します。
  • while read -r pattern1行に1つのパターンを読み、パターンを繰り返します。
  • "${pattern}"*シェルは、このパターンで始まるすべてのファイル名に展開されます。

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

代わりに、後で戻ることを許可することをお勧めしますcdpushdpopd

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

おすすめ記事