複数の値を変更する必要があるテーブルがあります。個々のファイルに適用すると、正しく機能sed
するさまざまなコマンドがあります。tr
しかし、このコマンドでループを作成したい場合はまったく機能しません。これは私のループです。
#!/bin/bash
in_dir=/home/stevens/SUMARIO/regional_model/data/basin
stations="almourol alton cuntan eldeim farakka koulikoro lobith louth olivenca stolb tangnaihai"
gcms="gfdl-esm2m hadgem2-es ipsl-cm5a-lr miroc-esm-chem noresm1-m"
scenarios="rcp8p5"
for station in ${stations};do
echo "go to directory"
cd ${in_dir}/${station}
for gcm in ${gcms};do
for rcp in ${rcps};do
cd ${in_dir}/${station}
echo "replace datum"
sed 's/"datum"/"YEAR-MONTH-DAY"/g' ${station}_${gcm}_${scenario} > ${station}_${gcm}_${scenario}.c
echo "delete hour"
sed 's/ 12:00:00//g' ${station}_${gcm}_${scenario}.c > ${station}_${gcm}_${scenario}.cs
echo "replace - to ;"
tr "-" ";" < ${station}_${gcm}_${scenario}.cs > ${station}_${gcm}_${scenario}.csv
rm ${station}_${gcm}_${scenario}.cs ${station}_${gcm}_${scenario}.c
done
done
done
このループがうまくいかない理由を知っている人はいますか?
答え1
rcps
まだ変数を定義していません。- 定義しましたが
scenarios
使用しました。scenario
以下は、これらの問題を解決し、その他の改善を適用したスクリプトのバージョンです。
- 読みやすくするために、改行とソートされたインデントを追加した形式
- スペースで区切られた文字列の代わりに配列を使用してください。
sed
何度も追加せずに一度だけ使用してくださいtr
- すべての変数を二重引用符で囲みます。
- すべての固定文字列を一重引用符で囲む
$fname
使用するたびに再構成するのではなく、生成されたファイル名()を保持するように変数()を定義するのは${station}_${gcm}_${scenario}
読みにくく、入力エラーが発生しやすいです。
#!/bin/bash
in_dir='/home/stevens/SUMARIO/regional_model/data/basin'
stations=(almourol alton cuntan eldeim farakka koulikoro lobith louth
olivenca stolb tangnaihai)
gcms=(gfdl-esm2m hadgem2-es ipsl-cm5a-lr miroc-esm-chem noresm1-m)
scenario='rcp8p5'
rcps=(a b c)
for station in "${stations[@]}" ; do
cd "${in_dir}/${station}"
for gcm in "${gcms[@]}"; do
for rcp in "${rcps[@]}" ; do
fname="${station}_${gcm}_${scenario}"
echo "replace datum: $fname"
sed -e 's/"datum"/"YEAR-MONTH-DAY"/g;
s/ 12:00:00//g;
s/-/;/g' "$fname" > "${fname}.csv"
done
done
done
文字列を実際の日付に置き換えるには、"datum"
次の手順を実行する必要があります。
YMD=$(date +%Y-%m-%d)
他の変数と配列として定義されています- そして、
sed
スクリプトを次のように書き直します。
sed -e 's/"datum"/"'"${YMD}"'"/g;
s/ 12:00:00//g;
s/-/;/g' "$fname" > "${fname}.csv"
しかし、複数のシーンを持つ予定の場合は、scenarios
別の配列として定義して別のループを追加する必要があります。for scenario in "${scenarios[@]}" ; do ..... done