Andreluiz
Andreluiz

Reputation: 55

AWK wrong math on first line only

This is the input file input.awk DOS type

06-13-2014,08:43:11
RLS007817                
RRC001021                
yes,71.61673,0,150,37,1
no,11,156,1.35,306.418
4,3,-1,2.5165,20,-1.4204
-4,0,11,0,0,0
1.00E-001,0.2,3.00E-001,0.6786031,0.5,6.37E-002
110,40,30,222,200,-539
120,50,35,215,220,-547
130,60,40,207,240,-553
140,70,45,196,260,-560
150,80,50,184,280,-566
160,90,55,170,300,-573
170,100,60,157,320,-578
180,110,65,141,340,-582
190,120,70,126,360,-586
200,130,75,110,380,-590

This is what I basically need:

BASH code

#!/bin/bash
myfile="input.awk"

vzeros=$(sed '6q;d' $myfile)
vshift=$(sed '7q;d' $myfile)
vcalib=$(sed '8q;d' $myfile)
IFS=','
read -a avz <<< "${vzeros}"
read -a avs <<< "${vshift}"
read -a avc <<< "${vcalib}"
z1=${avz[0]};s1=${avs[0]};c1=${avc[0]}
z2=${avz[1]};s2=${avs[1]};c2=${avc[1]}
z3=${avz[2]};s3=${avs[2]};c3=${avc[2]}
z4=${avz[4]};s4=${avs[4]};c4=${avc[4]}
#The single variables will be passed to awk
awk -v z1="$z1" -v c1="$c1" -v s1="$s1" -v z2="$z2" -v c2="$c2" -v s2="$s2" -v z3="$z3" -v c3="$c3" -v s3="$s3" -v z4="$z4" -v c4="$c4" -v s4="$s4"  'NR>8 { FS = "," ; 
nc1 =  c1 * ( $1 - z1 - s1 );
nc2 =  c2 * ( $2 - z2 - s2 ); 
nc3 =  c3 * ( $3 - z3 - s3 );
nc4 =  c4 * ( $5 - z4 - s4 ); 
print nc1,nc2,nc3,nc4 }' $myfile > test.plot

This is the result on the file test.plot

11 -0.6 -3 -10
12 9.4 7.5 100
13 11.4 9 110
14 13.4 10.5 120
15 15.4 12 130
16 17.4 13.5 140
17 19.4 15 150
18 21.4 16.5 160
19 23.4 18 170
20 25.4 19.5 180

This is the weird part... Only in the first line and after the first column all is wrong... And I have no idea why. This is the expected result file:

11  7.4 6   90
12  9.4 7.5 100
13  11.4    9   110
14  13.4    10.5    120
15  15.4    12  130
16  17.4    13.5    140
17  19.4    15  150
18  21.4    16.5    160
19  23.4    18  170
20  25.4    19.5    180

I've printed the correction factors captured from lines 6,7 & 8 and everything is fine. All math is fine, except on the first line, after the first column.

OS: Slackware 13.37.

AWK: GNU Awk 3.1.6 Copyright (C) 1989, 1991-2007 Free Software Foundation.

Upvotes: 1

Views: 347

Answers (2)

jrjc
jrjc

Reputation: 21883

Your sample is too complex to reproduce something, but I guess you should try :

 awk -F"," 'NR>8{...

instead of

awk 'NR>8 { FS = "," ;

You can also try with BEGIN:

awk 'BEGIN{FS=","}NR>8{...

I eventually tested your script, and you should change the position of the FS parameter, as I told you:

awk -v z1="$z1" -v c1="$c1" -v s1="$s1" -v z2="$z2" \
-v c2="$c2" -v s2="$s2" -v z3="$z3" -v c3="$c3" \
-v s3="$s3" -v z4="$z4" -v c4="$c4" -v s4="$s4" -F"," 'NR>8 { 
nc1 =  c1 * ( $1 - z1 - s1 );
nc2 =  c2 * ( $2 - z2 - s2 ); 
nc3 =  c3 * ( $3 - z3 - s3 );
nc4 =  c4 * ( $5 - z4 - s4 ); 
print nc1,nc2,nc3,nc4 }' $myfile

11 7.4 6 90
12 9.4 7.5 100
13 11.4 9 110
14 13.4 10.5 120
15 15.4 12 130
16 17.4 13.5 140
17 19.4 15 150
18 21.4 16.5 160
19 23.4 18 170
20 25.4 19.5 180
0 -0.6 -3 -10

Why you had a problem ?

Because awk parses the line before executing the block, so if you tell it to change something related to parsing, the changes will occur from the next line.

HTH

Upvotes: 1

shellter
shellter

Reputation: 37298

I agree with @jeanrjc.

I copied your file and script to my machine and reduced it to processing the first 2 lines of your data.

With your code as is, I duplicate your results, i.e.

#dbg $0=110,40,30,222,200,-539
#dbg c2=0.2 $2= z2=3 s2=0
11 -0.6 -3 -10

#dbg $0=120,50,35,215,220,-547
#dbg c2=0.2 $2= z2=3 s2=0
12 -0.6 -3 -10

With FS=","; commented out, and -F, added in the option list the output is what you are looking for.

#dbg $0=110,40,30,222,200,-539
#dbg c2=0.2 $2=40 z2=3 s2=0
11 7.4 6 90

#dbg $0=120,50,35,215,220,-547
#dbg c2=0.2 $2=50 z2=3 s2=0
12 9.4 7.5 100

So make sure you have removed the FS=","; from the block of code, and you are using -F, In any case, I would say, that resetting the FS="," for each line that is processed is not useful.

If that still doesn't solve it, try the corrected code on a machine with a newer version of awk.


It would take a small magazine article to completely illustrate what is happening while reading thru the first 8 records (when FS="[[:space:]]), the transition to the first row that meets your rule NR>8, the FS is still [:space:] when the fields are parsed, then, FS is set to ,, but that first row is not rescanned.

IHTH!

Upvotes: 2

Related Questions