0

I assigned output of piping into a variable, but when I try to use the variable to do math, it won't allow me:

%%bash
cd /data/ref/
grep -v ">" EN | wc -c > ref
cat ref
cd /example/
grep -v ">" SR | wc -l > sample
cat sample

echo $((x= cat sample, y= cat ref, u=x/y, z=u*100))

I get this error:

41858
38986
bash: line 7: x= cat sample, y= cat ref, u=x/y, z=u*100: syntax error in expression (error token is "sample, y= cat ref, u=x/y, z=u*100"
Cyrus
  • 84,225
  • 14
  • 89
  • 153
user432797
  • 593
  • 4
  • 13
  • 1
    @user432797 : The word _cat_ is not a number, nor a variable. Even if were a variable, the word _sample_ afterwards does not make sense. – user1934428 Oct 20 '20 at 05:09

1 Answers1

2

You received that error because you passed an invalid arithmetic expression into a bash arithetic expansion. Only an arithmetic expression is allowed for this place. What you try to do seems like this:

ref="$(grep -v ">" /data/ref/EN | wc -c)"
sample="$(grep -v ">" /example/SR | wc -l)"

# this is only integer division
#u=$(( sample / ref ))
#z=$(( 100 * u ))

# to do math calculations, you can use bc
u=$(bc <<< "scale=2; $sample/$ref")
z=$(bc <<< "scale=2; 100*$u")

printf "%d, %d, %.2f, %.2f\n" "$ref" "$sample" "$u" "$z"

so hopefully you get an output like this:

41858, 38986, 0.93, 93.00

Notes:

  • There is no need to cd before executing a grep, it accepts the full path with the target filename as an argument. So without changing directory, you can grep various locations.

  • In order to save the output of your command (which is only a number) you don't need to save it in a file and cat the file. Just use the syntax var=$( ) and var will be assigned the output of this command substitution.

  • Have in mind that / will result to 0 for the division 38986/41858 because it's the integer division. If you want to do math calculations with decimals, you can see this post for how to do them using bc.

  • To print anything, use the shell builtin printf. Here the last two numbers are formatted with 2 decimal points.

thanasisp
  • 5,855
  • 3
  • 14
  • 31
  • That was helpful @thanasisp, I was reading this but I couldn't see how to apply it to my question https://www.shell-tips.com/bash/math-arithmetic-calculation/ but your answer covered a lot. Now I have to learn printf, is there anything easier than printf to print the output directly? – user432797 Oct 20 '20 at 06:10
  • 1
    yes, use `echo "$ref" "$sample" "$u" "$z"` Have in mind that it prints with 2 decimal points because we passed scale=2 to bc, so we got this result. With `printf` you can interpolate text, do a lot of things, for printing just a variable echo is ok. – thanasisp Oct 20 '20 at 06:11