Add bash arithmetic section to notes
This commit is contained in:
parent
2331cc55ac
commit
8f06577f87
79
notes/shell/bash_arithmetic.md
Normal file
79
notes/shell/bash_arithmetic.md
Normal file
|
@ -0,0 +1,79 @@
|
|||
# Working with numbers in bash
|
||||
Bash interprets everything by default as a string, however it can also work with
|
||||
numbers, just be careful with your conditional operators
|
||||
|
||||
## Storing numbers
|
||||
`declare` and `local` both can make integer variables with the `-i` flag
|
||||
|
||||
```bash
|
||||
declare -i a=2
|
||||
|
||||
f () { local -i a=3 ;}
|
||||
```
|
||||
|
||||
Variables can be manipulated in double parenthesis, very similar to c/python.
|
||||
Use `$(())` to return the value instead. Edges and centers seem whitespace
|
||||
insensitive. No need to `$` in front of variables inside `(())`
|
||||
|
||||
Work as expected: `+ - * %`
|
||||
Exponent: `**`
|
||||
Floored division: `/`
|
||||
|
||||
```bash
|
||||
declare -i a=2 b=3 # Multiple on the same line are fine
|
||||
|
||||
(( a++ )) # a == 3
|
||||
(( a+=b )) # a == 6
|
||||
(( a = 2 )) # a == 2
|
||||
((a=4+b)) # a == 7
|
||||
(( a = 4 + b )) # Spacing is optional, same as above
|
||||
|
||||
declare -i c=$((a**b + 4)) # c == 7**3 + 4 == 347
|
||||
```
|
||||
|
||||
## Using numbers
|
||||
Conditionals are different for numbers in bash. Mapping c to bash:
|
||||
|
||||
```
|
||||
C | Bash
|
||||
----|-----
|
||||
== | -eq
|
||||
!= | -ne
|
||||
> | -gt
|
||||
< | -lt
|
||||
>= | -ge
|
||||
<= | -le
|
||||
```
|
||||
|
||||
```bash
|
||||
declare -i a=3 b=2
|
||||
|
||||
if [[ $((a**b)) -ge 1000 ]]; then
|
||||
echo "Exponentiation with ${a}^${b} is pretty big"
|
||||
elif [[ $a -lt $b ]]; then
|
||||
echo "$a is smaller than $b"
|
||||
else
|
||||
echo "$a isn't smaller than $b"
|
||||
fi
|
||||
|
||||
echo "You rolled a: $(( RANDOM % 6 + 1 )) on a 6 sided dice"
|
||||
```
|
||||
|
||||
## Floats
|
||||
Bash has no support for floats, don't even try. If you need floats, use awk,
|
||||
which has full support. To still sort of use rational numbers in bash, store a
|
||||
numerator and denominator, then pass both to awk when you need the float
|
||||
|
||||
```bash
|
||||
declare -i num_1=4 denom_1=9
|
||||
declare -i num_2=2 denom_2=9
|
||||
|
||||
(( num_1 += num_2 ))
|
||||
|
||||
awk -v n1=$num_1 -v d1=$denom_1 -v n2=$num_2 -v d2=$denom_2 \
|
||||
'BEGIN { printf "%.2f\n", n1/d1 + n2/d2 }'
|
||||
```
|
||||
|
||||
Bash has floored division `/` and remainders `%`, though the awk approach is
|
||||
easier. Note awk's syntax is identical to c, so it uses `^` for exponentiation
|
||||
and the standard `==`, `<=`... for comparison
|
|
@ -35,11 +35,15 @@ visual mode
|
|||
:21 Goes to line 21. ^ and $ are for the first and last line
|
||||
:10,20d Deletes lines 10 through 20, inclusive on both ends
|
||||
:u[ndo] Undoes the last action
|
||||
:mark a Makes a mark at a. From vim
|
||||
:ka Also makes a mark at a. From ex
|
||||
:'a Go to mark a
|
||||
:g/re/p Globally exectute a command on lines with /re/
|
||||
:v/re/p Inverse of :g. Executes on all lines without /re/
|
||||
:3,6co$ Copy lines [3,6] to the end of the document
|
||||
:3m6 Move line 3 to line 6
|
||||
:z=3 Pretty print lines in [-2,+2]
|
||||
:norm! @l Execute keystrokes, if all else fails
|
||||
```
|
||||
|
||||
Several commands can be chained with `|`, similar to `;` in bash
|
||||
|
|
Loading…
Reference in a new issue