Wednesday, October 26, 2022

[SOLVED] BASH: Performing decimal division on a column in file and printing result in another file

Issue

I have a file (in.txt) with the following columns:

# DM      Sigma      Time (s)     Sample    Downfact
78.20    7.36    134.200512    2096883      70
78.20    7.21    144.099904    2251561      70
78.20    9.99    148.872384    2326131     150
78.20   10.77    283.249664    4425776      45

                                                                                                       

I want to write a bash script to divide all values in column 'Time' by 0.5867, get a precision up to 2 decimal points and print out the resulting values in another file out.txt

I tried using bc/awk but it gives this error.

awk: cmd. line:1: fatal: division by zero attempted
awk: fatal: cannot open file `file' for reading (No such file or directory)

Could someone help me with this? Thanks.

This is the bash script that I attempted:

cat in.txt | while read DM Sigma Time Sample Downfact; do
echo "$DM      $Sigma      $Time     $Sample    $Downfact"                                                                                            
pperiod = 0.5867                                                                                                                                                                                                                                                                                                         
awk -v n=$Time 'BEGIN {printf "%.2f\n", (n/$pperiod)}'                                                                                                  
#echo "scale=2 ; $Time / $pperiod" | bc                                                                                                                 
#echo "$subint" > out.txt                                                                                                                            
done  

I expected the script to divide column 'Time' with pperiod and get the result with a precision of 2 decimal places. This result should be printed to a file named out.txt


Solution

Lots of issues with current awk code:

  • need to pass in the value of the $pperiod variable
  • need to reference the Time column by is position ($3 in this case)
  • BEGIN{} block is applied before any input lines are processed and has nothing to do with processing of actual input lines
  • there is no code to perform processing on actual input lines
  • need to decide what to do in the case of a divide by zero scenario (in this case we'll default answer to 0.00)
  • NOTE: current code generates divide by zero error because $pperiod is an undefined (awk) variable which in turn defaults to 0
  • additionally, pperiod = 0.5867 is invalid bash syntax

One idea for fixing current issues:

pperiod=0.5867 
awk -v pp="${pperiod}" 'NR>1 {printf "%.2f\n", (pp==0 ? 0 : ($3/pp))}' in.txt > out.txt

Where:

  • -v pp="${pperiod}" - assign awk variable pp the value of the bash variable "${pperiod}"
  • NR>1 - skip header line
  • NR>1 {printf "%.2f\n" ...}- for each input line, other than the header line, print the result of dividing theTimecolumn (aka$3) by the value of the awkvariablepp(which holds the value of thebashvariable"${pperiod}"`)
  • (pp==0 ? 0 : ($3/pp)) - if pp is equal 0 we print 0 else print result of $3/pp) (this keeps us from generating a divide by zero error)
  • NOTE: this also eliminates the need for the cat|while loop

This generates:

$ cat out.txt
228.74
245.61
253.75
482.78


Answered By - markp-fuso
Answer Checked By - Robin (WPSolving Admin)