Home > Enterprise >  divide floating point numbers from two different outputs
divide floating point numbers from two different outputs

Time:10-24

I am writing a bash script that has 1) number of lines in a file matching a pattern and 2) total lines in a file.

a) To get the number of lines in a file within a directory that had a specific pattern I used grep -c "pattern" f*

b) For overall line count in each file within the directory I used wc -l f*

I am trying to divide the output from 2 by 1. I have tried a for loop

for i in $a
do
printf "%f\n" $(($b/$a)
echo i
done

but that returns an error syntax error in expression (error token is "first file in directory")

I also have tried

bc "$b/$a" 

which does not work either

I am not sure if this is possible to do -- any advice appreciated. thanks!

Sample: grep -c *f generates a list like this

myfile1 500
myfile2 0
myfile3 14
myfile4 18

and wc -l *f generates a list like this:

myfile1 500
myfile2 500
myfile3 500
myfile4 238

I want my output to be the outcome of output for grep/wc divided so for example

myfile1 1
myfile2 0
myfile3 0.28
myfile4 0.07

CodePudding user response:

bash only supports integer math so the following will print the (silently) truncated integer value:

$ a=3 b=5
$ printf "%f\n" $(($b/$a))
1.000000

bc is one solution and with a tweak of OP's current code:

$ bc <<< "scale=2;$b/$a"
1.66

# or

$ echo "scale=4;$b/$a" | bc
1.6666

If you happen to start with real/float numbers the printf approach will error (more specifically, the $(($b/$a)) will generate an error):

$ a=3.55 b=8.456
$ printf "%f\n" $(($b/$a))
-bash: 8.456/3.55: syntax error: invalid arithmetic operator (error token is ".456/3.55")

bc to the rescue:

$ bc <<< "scale=2;$b/$a"
2.38

# or

$ echo "scale=4;$b/$a" | bc
2.3819

NOTE: in OP's parent code there should be a test for $a=0 and if true then decide how to proceed (eg, set answer to 0; skip the calculation; print a warning message) otherwise the this code will generate a divide by zero error

CodePudding user response:

This awk will do it all:

awk '/pattern/{a =1}END{print a/NR}' f*

CodePudding user response:

bash doesn't have builtin floating-point arithmetic, but it can be simulated to some extent. For instance, in order to truncate the result of the division a/b (a and b are integers) to two decimal places (without rounding):

q=$((100*a/b)) # hoping multiplication won't overflow
echo ${q:0:-2}.${q: -2}

The number of decimal places can be made parametric:

n=4
q=$((10**n*a/b))
echo ${q:0:-n}.${q: -n}
  • Related