awk if statement with simple math

送分小仙女□ 提交于 2019-12-14 02:03:23

问题


I'm just trying to do some basic calculations on a CSV file.

Data:

31590,Foo,70
28327,Bar,291
25155,Baz,583
24179,Food,694
28670,Spaz,67
22190,bawk,4431
29584,alfred,142
27698,brian,379
24372,peter,22
25064,weinberger,8

Here's my simple awk script:

#!/usr/local/bin/gawk -f
BEGIN { FPAT="([^,]*)|(\"[^\"]+\")"; OFS=","; OFMT="%.2f"; }
    NR > 1
END { if ($3>1336) $4=$3*0.03; if ($3<1336) $4=$3*0.05;}1**

Wrong output:

31590,Foo,70
28327,Bar,291
28327,Bar,291
25155,Baz,583
25155,Baz,583
24179,Food,694
24179,Food,694
28670,Spaz,67
28670,Spaz,67
22190,bawk,4431
22190,bawk,4431
29584,alfred,142
29584,alfred,142
27698,brian,379
27698,brian,379
24372,peter,22
24372,peter,22
25064,weinberger,8
25064,weinberger,8

Excepted output:

31590,Foo,70,3.5
28327,Bar,291,14.55
25155,Baz,583,29.15
24179,Food,694,34.7
28670,Spaz,67,3.35
22190,bawk,4431,132.93
29584,alfred,142,7.1
27698,brian,379,18.95
24372,peter,22,1.1
25064,weinberger,8,.04

Simple math is if field $3 > 1336 = $3*.03 and results in field $4 field $3 < 1336 = $3*.05 and results in field $4


回答1:


There's no need to force awk to recompile every record (by assigning to $4), just print the current record followed by the result of your calculation:

awk 'BEGIN{FS=OFS=","; OFMT="%.2f"} {print $0, $3*($3>1336?0.03:0.05)}' file



回答2:


You shouldn't have anything in the END block

BEGIN {
    FS = OFS = ","
    OFMT="%.2f"
}
{
    if ($3 > 1336) 
        $4 = $3 * 0.03
    else 
        $4 = $3 * 0.05        
    print
}

This results in

31590,Foo,70,3.5
28327,Bar,291,14.55
25155,Baz,583,29.15
24179,Food,694,34.7
28670,Spaz,67,3.35
22190,bawk,4431,132.93
29584,alfred,142,7.1
27698,brian,379,18.95
24372,peter,22,1.1
25064,weinberger,8,0.4



回答3:


$ awk -F, -v OFS=, '{if ($3>1336) $4=$3*0.03; else $4=$3*0.05;} 1' data
31590,Foo,70,3.5
28327,Bar,291,14.55
25155,Baz,583,29.15
24179,Food,694,34.7
28670,Spaz,67,3.35
22190,bawk,4431,132.93
29584,alfred,142,7.1
27698,brian,379,18.95
24372,peter,22,1.1
25064,weinberger,8,0.4

Discussion

The END block is not executed at the end of each line but at the end of the whole file. Consequently, it is not helpful here.

The original code has two free standing conditions, NR>1 and 1. The default action for each is to print the line. That is why, in the "wrong output," all lines after the first were doubled in the output.




回答4:


With awk:

awk -F, -v OFS=, '$3>1336?$4=$3*.03:$4=$3*.05' file

The conditional-expression ? action1 : action2 ; is the much shorter terinary operator in awk.



来源:https://stackoverflow.com/questions/30768420/awk-if-statement-with-simple-math

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!