Eric
Eric

Reputation: 41

Trying to get an average using the contents of two files

So I have two files in my directory that contain a number in each of them. I want to make a script that calculates the average of these two numbers. How would I write it? Would this be correct?

avg=$((${<file1.txt}-${<file2.txt})/2)

Upvotes: 1

Views: 62

Answers (2)

reflective_mind
reflective_mind

Reputation: 1525

Your example does not work. Furthermore, your formula is probably incorrect. Here are two options without unnecessary cat:

avg=$(( (`<file1.txt` + `<file2.txt`) / 2 ))

or

avg=$(( ($(<file1.txt) + $(<file2.txt)) / 2 ))

I find the first one more readable though. Also be warned: this trivial approach will cause problems when your files contain more than just the plain numbers.

EDIT:

I should have noted that the first syntactical/legacy option which uses the backticks (` `) is no longer recommended and should be avoided. You can read more about the WHY here. Thanks at mklement0 for the link!

EDIT2:

According to Eric, the values are floating point numbers. You can't do this directly in bash because only integer numbers are supported. You have to use a little helper:

avg=$(bc <<< "( $(<file1.txt) + $(<file2.txt) ) / 2")

or maybe easier to understand

avg=$(echo "( $(<file1.txt) + $(<file2.txt) ) / 2" | bc)

For those who might wonder what bc is (see man bc):

bc is a language that supports arbitrary precision numbers with interactive execution of statements.


Here is another alternative since perl is usually installed by default:

avg=$(perl -e 'print( ($ARGV[0] + $ARGV[1]) / 2 )' -- $(<file1.txt) $(<file2.txt))

Upvotes: 1

l0b0
l0b0

Reputation: 58998

You'll want to use a command substitution:

avg=$(($(cat file1.txt)-$(cat file2.txt)/2))

However, Bash is a pretty bad language for doing maths (at least unless it's completely integer maths). You might want to look into bc or a "real" language like Python.

Upvotes: 0

Related Questions