5

Say I have these two input files:

> file1
2
3
4

> file2
10
100
1000

And I would like to compute: file1/file2 for each line, resulting in file3:

> file 3
0.2
0.03
0.004

Divisions in bash can be achieved by: $((file1_line/file2_line))

  • 1
    What's the exact question? – schaiba Aug 22 '16 at 8:59
11

A paste and bc combination is a good choice for simple arithmetic:

paste -d/ file1 file2 | bc -l

Output:

.2000000000
.0300000000
.0040000000

A more advanced example

With some trickery you can get a bit more complicated. Say file3 contains:

6
7
8

You can do (file1 + file3) / file2 like this:

paste -d'(+)/' /dev/null file1 file3 /dev/null file2

Output:

(2+6)/10
(3+7)/100
(4+8)/1000

This works because paste cycles through its delimiter list for each line.

React to divide-by-zero

Illigal operations sent to bc result in a warning being sent to standard error. You could redirect these to a different file and decide program flow based on its content, e.g.:

paste -d/ file1 file2 | bc -l > resultfile 2> errorfile
if grep -q 'Divide by zero' errorfile; then
  echo "Error in calculation"
else
  echo "All is well"
fi

Or if there was any error:

paste -d/ file1 file2 | bc -l > resultfile 2> errorfile
if ! file errorfile | grep -q empty; then
  echo "Error in calculation"
else
  echo "All is well"
fi
  • Thanks @Thor. Do you think it is possible to integrate an exit/skip status for any division by zero? As in: unix.stackexchange.com/questions/28016/… – dovah Aug 22 '16 at 9:19
  • @dovah: bc gives you a divide-by-zero warning, so it should be straightforward to integrate. It just depends on what you mean by that – Thor Aug 22 '16 at 9:23
  • 1
    @dovah: Added a divide-by-zero example – Thor Aug 22 '16 at 11:49
7

start with

 paste file1 file2 | awk '{printf "%f\n",$1/$2 } '

where

  • paste will "merge" file
  • awk will compute division, one at a time.

if you don't like too many trailling 0's, just add

... | sed -e s/0*\$//

to exit in case of 0

paste file1 file2 | awk '!$2 {exit ; }  {printf "%f\n",$1/$2 } '
  • 1
    With awk you needn't paste awk '{getline a <"file2";print $1/a}' file1 – Costas Aug 22 '16 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.