在不使用循环的情况下使用 bc 对数字列表执行操作
Performing an operation on a list of numbers with bc without using a loop
我有一个数字列表,我想在 BASH 中对其执行操作(例如正弦、sqrt 等)。目前我使用 bc 遍历数字向量并添加 space " "
,这看起来有点笨拙:
x=`seq 1 2.5 30` # generate a list of numbers
for i in $x ; do
a=${a}`echo "sqrt($i)" | bc`" "
done # a is output vector
我想知道是否有更简洁的方法可以在不使用循环和 " "
标记的情况下执行此操作?
而不是为每个数字调用 bc
,您可以像这样使用单个 awk:
awk -v b=1 -v e=30 'BEGIN{for (i=b; i<=e; i+=2.5) printf "%.1f\n", sqrt(i)}'
1.0
1.9
2.4
2.9
3.3
3.7
4.0
4.3
4.6
4.8
5.1
5.3
要将输出存储在数组中,请使用:
arr=($(awk -v b=1 -v e=30 'BEGIN{for (i=b; i<=e; i+=2.5) printf "%.1f\n", sqrt(i)}'))
然后使用以下方式打印输出:
printf '%s\n' "${arr[@]}"
您不是在构建数组,而是在构建带空格的字符串。您可以改用实际数组:
for x in $(seq 1 2.5 30); do
a+=( $(bc <<< "sqrt($x)") )
done
printf '%s\n' "${a[@]}"
导致
1
1.8
2.4
2.9
3.3
3.6
4.0
4.3
4.5
4.8
5.0
5.3
或者,您可以完全用 bc 编写它以避免为每一行生成一个子 shell:
#!/usr/bin/bc
for (x = 1; x <= 30; x += 2.5) {
sqrt(x)
}
quit
如果将其填充到名为 getsquares
的脚本中,则可以使用
获取数组
a=($(./getsquares))
或者,两全其美(bc 的单个实例,嵌入在 Bash 脚本中):
a=($(bc <<< 'for (x = 1; x <= 30; x += 2.5) sqrt(x)'))
使用 bash,特别是 mapfile
将命令的输出存储到数组中:
$ mapfile -t nums < <(seq 1 2.5 30)
$ mapfile -t sqrts < <(printf "sqrt(%f)\n" "${nums[@]}" | bc -l)
$ printf "%s\n" "${sqrts[@]}"
1
1.87082869338697069279
2.44948974278317809819
2.91547594742265023543
3.31662479035539984911
3.67423461417476714729
4.00000000000000000000
4.30116263352131338586
4.58257569495584000658
4.84767985741632901407
5.09901951359278483002
5.33853912601565560540
我有一个数字列表,我想在 BASH 中对其执行操作(例如正弦、sqrt 等)。目前我使用 bc 遍历数字向量并添加 space " "
,这看起来有点笨拙:
x=`seq 1 2.5 30` # generate a list of numbers
for i in $x ; do
a=${a}`echo "sqrt($i)" | bc`" "
done # a is output vector
我想知道是否有更简洁的方法可以在不使用循环和 " "
标记的情况下执行此操作?
而不是为每个数字调用 bc
,您可以像这样使用单个 awk:
awk -v b=1 -v e=30 'BEGIN{for (i=b; i<=e; i+=2.5) printf "%.1f\n", sqrt(i)}'
1.0
1.9
2.4
2.9
3.3
3.7
4.0
4.3
4.6
4.8
5.1
5.3
要将输出存储在数组中,请使用:
arr=($(awk -v b=1 -v e=30 'BEGIN{for (i=b; i<=e; i+=2.5) printf "%.1f\n", sqrt(i)}'))
然后使用以下方式打印输出:
printf '%s\n' "${arr[@]}"
您不是在构建数组,而是在构建带空格的字符串。您可以改用实际数组:
for x in $(seq 1 2.5 30); do
a+=( $(bc <<< "sqrt($x)") )
done
printf '%s\n' "${a[@]}"
导致
1
1.8
2.4
2.9
3.3
3.6
4.0
4.3
4.5
4.8
5.0
5.3
或者,您可以完全用 bc 编写它以避免为每一行生成一个子 shell:
#!/usr/bin/bc
for (x = 1; x <= 30; x += 2.5) {
sqrt(x)
}
quit
如果将其填充到名为 getsquares
的脚本中,则可以使用
a=($(./getsquares))
或者,两全其美(bc 的单个实例,嵌入在 Bash 脚本中):
a=($(bc <<< 'for (x = 1; x <= 30; x += 2.5) sqrt(x)'))
使用 bash,特别是 mapfile
将命令的输出存储到数组中:
$ mapfile -t nums < <(seq 1 2.5 30)
$ mapfile -t sqrts < <(printf "sqrt(%f)\n" "${nums[@]}" | bc -l)
$ printf "%s\n" "${sqrts[@]}"
1
1.87082869338697069279
2.44948974278317809819
2.91547594742265023543
3.31662479035539984911
3.67423461417476714729
4.00000000000000000000
4.30116263352131338586
4.58257569495584000658
4.84767985741632901407
5.09901951359278483002
5.33853912601565560540