仅在第一行AWK错误的数学

时间:2015-01-22 15:50:54

标签: csv math awk

这是输入文件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

这是我基本上需要的:

  • 忽略前8行(确定)
  • 选择并分割第6,7行和第6行的数字。 8(好的)
  • 对列进行AWK数学运算(仅在第一行出错?)

BASH代码

#!/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

这是文件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

这是奇怪的部分... 只在第一行和第一列之后都是错误的。 ..我不知道为什么。 这是预期的结果文件:

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

我打印了从第6,7和6行中捕获的校正因子。 8,一切都很好。所有数学都很好,除了第一行之后的第一行。

操作系统:Slackware 13.37。

AWK:GNU Awk 3.1.6版权所有(C)1989,1991-2007自由软件基金会。

2 个答案:

答案 0 :(得分:2)

我同意@jeanrjc。

我将您的文件和脚本复制到我的机器上并将其缩小为处理数据的前两行。

根据您的代码,我会复制您的结果,即

#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

注释掉FS=",";,并在选项列表中添加了-F,,输出就是您要查找的内容。

#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

因此,请确保您已从代码块中删除了FS=",";,并且您正在使用-F,无论如何,我会说,为每一行重置FS=","处理没用。

如果仍然无法解决问题,请在具有较新版本awk的计算机上尝试更正的代码。


在阅读前8个记录(FS="[[:space:]]时),过渡到符合规则NR>8的第一行,FS时,需要一篇小杂志文章来完整地说明正在发生的事情。在解析字段时仍为[:space:],然后,FS设置为,,但第一行未重新扫描。

IHTH!

答案 1 :(得分:1)

你的样本太复杂而无法复制,但我想你应该尝试:

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

而不是

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

您也可以尝试使用BEGIN:

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

我最终测试了你的脚本,你应该改变FS参数的位置,正如我告诉你的那样:

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

为什么遇到问题?

因为awk在执行块之前解析该行,所以如果你告诉它改变与解析相关的东西,那么改变将从下一行发生。

HTH