diff --git a/notes/shell/bash_arithmetic.md b/notes/shell/bash_arithmetic.md new file mode 100644 index 0000000..39586d3 --- /dev/null +++ b/notes/shell/bash_arithmetic.md @@ -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 diff --git a/notes/vim/vim_batch_editing.md b/notes/vim/vim_batch_editing.md index 16824ca..4aadf4e 100644 --- a/notes/vim/vim_batch_editing.md +++ b/notes/vim/vim_batch_editing.md @@ -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