arithmetic progression
搜参数时,参数空间可能由一些散装的值和一个等差/比数列组成,如:
…tune
α
\alpha
α from 0.01, 0.99, and 0.1 to 0.9 at an increment of 0.1 per step…
其中 0.01 和 0.99 是没什么规律的散装值,0.1 ~ 0.9 是等差数列。在 shell 中要放在同一个数组里,可以写作:
ALPHA=(0.01 0.99 `seq 0.1 0.1 0.9`)
echo ${ALPHA[@]} # 0.01 0.99 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
等差数列可以简单由 seq
生成,其中三个参数顺序是初值、步长、终值,是闭区间(而不是前闭后开)。
geometric progression
等比就是把等差放上指数,要额外的运算命令。bc
在 docker 镜像中可能没有,可以用 awk
,如:
…
λ
\lambda
λ from 0.01 to 10 at a product of 10 per step…
写成:
LAMBDA=($(seq -2 1 1 | awk '{print 10^$1}')) # 套一层括号稳一点,见下一节
echo ${LAMBDA[@]} # 0.01 0.1 1 10
potential bug
有两种遍历的写法:
- 枚举下标,再用下标索引
- 直接枚举值
枚举下标可以用来同步遍历多个数组(即 python 的 zip
),但这种方法在生成序列时不套括号的话会出事;枚举值套不套都行,在遍历单个数组时方便。
echo --- 1. A、B 双双出事
A=$(seq 1 1 5) # 没套括号
B=${A[@]} # 也没套
for _a in $(seq 0 `expr ${#A[@]} - 1`); do
a=${A[_a]}
for _b in $(seq 0 `expr ${#B[@]} - 1`); do
b=${B[_b]}
echo a: $a, b: $b # 会一次过输出「a: 1 2 3 4 5, b: 1 2 3 4 5」
done
done
echo --- 2. C 正常,D 出事
C=($(seq 1 1 5)) # 套了
D=${C[@]} # 没套
for _c in $(seq 0 `expr ${#C[@]} - 1`); do
c=${C[_c]}
for _d in $(seq 0 `expr ${#D[@]} - 1`); do
d=${D[_d]}
echo c: $c, d: $d # 形如「c: 1, d: 1 2 3 4 5」
done
done
echo --- 3. E、F 都正常
E=($(seq 1 1 5)) # 套了
F=(${E[@]}) # 套了
for _e in $(seq 0 `expr ${#E[@]} - 1`); do
e=${E[_e]}
for _f in $(seq 0 `expr ${#F[@]} - 1`); do
f=${F[_f]}
echo e: $e, f: $f # 形如「e: 1, f: 1」
done
done
echo --- 4. 套不套都行写法
for a in ${A[@]}; do
for b in ${B[@]}; do
echo a: $a, b: $b # 形如「a: 1, b: 1」
done
done
for c in ${C[@]}; do
for d in ${D[@]}; do
echo c: $c, d: $d # 形如「c: 1, d: 1」
done
done
for e in ${E[@]}; do
for f in ${F[@]}; do
echo e: $e, f: $f # 形如「e: 1, f: 1」
done
done
References
- Shell中使用seq生成等差数组
- Shell数组拼接,Shell数组合并
- How to concatenate arrays in bash?
- Linux awk 命令
- awk 简单用法(内置函数)