我有一些表,我需要替换其中的几个值。我有不同的命令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