Simple math statements in bash in a for loop

2020-06-18 05:43发布

I'm quite new to bash scripting and usually avoid it all costs but I need to write a bash script to execute some simple things on a remote cluster. I'm having problems with a for loop that does the following:

for i in {1..20}
do
    for j in {1..20}
    do
        echo (i*i + j*j ) **.5  <--- Pseudo code!
    done
done

Can you help me with this simple math? I've thrown $'s everywhere and can't write it properly. If you could help me understand how variables are named/assigned in bash for loops and the limitations of bash math interpretation (how do you do the square root?) I'd be very grateful. Thanks!

11条回答
够拽才男人
2楼-- · 2020-06-18 06:22

Another form of integer math expressions in Bash puts the double parentheses on the outside of the entire expression for assignment operations:

(( var = i ** 2 ))
(( i++ ))
(( position += delta ))

As you can see, dollar signs are not needed here (nor inside $(())). Also, spaces are permitted around the equal sign.

Also, this form can be used in conditionals:

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}."

Or you can replace all that with this, of course:

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 also has a let statement:

let a=2**16
let 'a>>=1'    # bitwise shift - some operations need to be quoted or escaped
(( a>>=1 ))    # but not inside (())
查看更多
叛逆
3楼-- · 2020-06-18 06:23

Use double paren to evaluate a variable.

variableA=$((variableB*variableC))

Only for ints though.

查看更多
够拽才男人
4楼-- · 2020-06-18 06:27

Shell math can be done in several ways.

echo $(( i*i + j*j ))
echo $[ i*i + j*j ]
expr "$i" '*' "$i" '+' "$j" '*' "$j"

However, this can only handle integer arithmetic. Instead, you can use bc:

echo "scale = 5; sqrt( $i*$i + $j*$j)" | bc

Change scale to the number of decimal places desired.

查看更多
叼着烟拽天下
5楼-- · 2020-06-18 06:29

Here's a decent solution:

for i in {1..20}
do
   for j in {1..20}
   do
       echo "scale = 3; sqrt($i*$i + $j*$j)" | bc
   done
done

Output will be:

1.414
2.236
3.162
2.236
[...etc...]
查看更多
Fickle 薄情
6楼-- · 2020-06-18 06:32

The code

echo $[(($i * $i) + ($j * $j)) ** $X]

will work if $X is an integer. You're trying to take the square root, and I'm not sure if bash's built-in arithmetic will do that. You'll probably be better off using a more powerful calculator tool (like bc, et al.) for this.

查看更多
登录 后发表回答