我很擅长bash脚本并且通常会避免所有成本,但我需要编写一个bash脚本来执行远程集群上的一些简单的事情。我遇到了一个执行以下操作的for循环问题:
for i in {1..20}
do
for j in {1..20}
do
echo (i*i + j*j ) **.5 <--- Pseudo code!
done
done
你能帮我解决这个简单的数学问题吗?我到处扔了$
,无法正确编写。如果你能帮助我理解变量在bash for循环中的命名/赋值方式以及bash数学解释的局限性(你如何做平方根?)我将非常感激。谢谢!
答案 0 :(得分:11)
算术扩展需要$((...))
表示法,例如:
echo $((i*i + j*j))
但是,bash只使用整数,因此您可能需要使用外部工具,例如dc。
E.g。
dc -e "18k $i $i * $j $j * + v p"
答案 1 :(得分:8)
这是一个不错的解决方案:
for i in {1..20}
do
for j in {1..20}
do
echo "scale = 3; sqrt($i*$i + $j*$j)" | bc
done
done
输出将是:
1.414
2.236
3.162
2.236
[...etc...]
答案 2 :(得分:2)
Shell数学可以通过多种方式完成。
echo $(( i*i + j*j ))
echo $[ i*i + j*j ]
expr "$i" '*' "$i" '+' "$j" '*' "$j"
但是,这只能处理整数运算。相反,您可以使用bc
:
echo "scale = 5; sqrt( $i*$i + $j*$j)" | bc
将scale
更改为所需的小数位数。
答案 3 :(得分:2)
#!/bin/bash
for i in {1..20}; do
for j in {1..20}; do
echo 5k$i $i\* $j $j\*+vp | dc
done
done
答案 4 :(得分:1)
你的远程集群只有bash吗?如果没有,试试看你是否有awk
awk 'BEGIN{
for(i=1;i<=20;i++){
for(j=1;j<=20;j++){
print ( i*i + j*j ) ** 0.5
}
}
}'
答案 5 :(得分:0)
使用double paren来评估变量。
变量'S = $((可变*变量))
虽然只是为了投注。
答案 6 :(得分:0)
通常你会使用$((1 * 3)),但你的情况不会起作用,因为bash不支持浮点数。你必须使用像awk,bc或dc这样的外部工具: http://mywiki.wooledge.org/BashFAQ/022
答案 7 :(得分:0)
代码
echo $[(($i * $i) + ($j * $j)) ** $X]
如果$X
是整数,将起作用。你试图取平方根,我不确定bash的内置算法是否会这样做。你可能会更好地使用更强大的计算器工具(如bc
等)。
答案 8 :(得分:0)
Bash不提供数学函数。但是,您几乎肯定安装了korn shell。这应该有效:
#!/bin/ksh
for i in {1..20}
do
for j in {1..20}
do
x=$((sqrt(i*i + j*j)))
echo "sqrt($i^2 + $j^2) = $x"
done
done
输出的开头是
sqrt(1^2 + 1^2) = 1.41421356237309505
sqrt(1^2 + 2^2) = 2.2360679774997897
sqrt(1^2 + 3^2) = 3.16227766016837933
sqrt(1^2 + 4^2) = 4.12310562561766055
sqrt(1^2 + 5^2) = 5.09901951359278483
sqrt(1^2 + 6^2) = 6.08276253029821969
sqrt(1^2 + 7^2) = 7.07106781186547524
sqrt(1^2 + 8^2) = 8.06225774829854965
sqrt(1^2 + 9^2) = 9.05538513813741663
sqrt(1^2 + 10^2) = 10.0498756211208903
答案 9 :(得分:0)
使用zsh,这将起作用
for i in {1..20};do
for j in {1..20};do
echo $((($i*$i + $j*$j)**.5))
done
done
答案 10 :(得分:-1)
Bash中的另一种整数数学表达式将双括号放在整个表达式的外部以进行赋值操作:
(( var = i ** 2 ))
(( i++ ))
(( position += delta ))
如您所见,此处不需要美元符号(也不需要$(())
内)。此外,等号周围允许有空格。
此外,此表格可用于条件:
sixpacks=8 # note spaces not allowed here
(( beerprice = 8 )) # but you can use spaces this way
budget=50
# you can do assignments inside a conditional just like C
until (( (( beertotal = sixpacks * beerprice )) <= budget ))
do
(( sixpacks-- ))
done
echo "Buy ${sixpacks} six-packs at \$${beerprice} each for a total of \$${beertotal}."
或者你可以用这个代替所有这些:当然:
beerprice=8
budget=50
# integer division
(( sixpacks = budget / beerprice ))
(( beertotal = sixpacks * beerprice ))
echo "Buy ${sixpacks} six-packs at \$${beerprice} each for a total of \$${beertotal}."
Bash也有一个let
声明:
let a=2**16
let 'a>>=1' # bitwise shift - some operations need to be quoted or escaped
(( a>>=1 )) # but not inside (())