简体   繁体   English

shell scripting-bash中的算术计算

[英]Arithmetic calculation in shell scripting-bash

I have an input notepad file as shown below: 我有一个输入记事本文件,如下所示:

sample input file: 样本输入文件:

vegetables and rates 蔬菜和费率

kg  rate    total 
Tomato  4   50  100
potato  2   60  120 
Beans   3   80  240

Overalltotal: (100+120++240) = 460 总数:(100 + 120 ++ 240)= 460

I need to multiply the column 2 and column 3 and check the total if it is right and the overall total as well. 我需要将第2列和第3列相乘,并检查总数是否正确以及总数。 If that's not right we need to print in the same file as an error message as shown below 如果不正确,我们需要在同一文件中打印一条错误消息,如下所示

enter code here 在这里输入代码

sample output file: 样本输出文件:

vegetables and rates 蔬菜和费率

kg  rate    vegtotal

Tomato  4   50  200
potato  2   60  120 
Beans   3   80  240

Overalltotal: (200+120++240) = 560 总数:(200 + 120 ++ 240)= 560

Error in calculations: Vegtotal for tomato is wrong: It should be 200 instead of 100 Overalltotal is wrong: It should be 560 instead of 460 计算错误:西红柿的蔬菜错误:应该是200而不是100总体错误:应该是560而不是460

Code so far: 到目前为止的代码:

for f in Date*.log; do
       awk 'NR>1{ a[$1]=$2*$3 }{ print }END{ printf("\n");
            for(i in a)
       { if(a[i]!=$4)
              { print i,"Error in calculations",a[i] }
            } }' "$f" > tmpfile && mv tmpfile "$f"; 

done

It calculates the total but not comparing the values. 它计算总计,但不比较值。 How can I compare them and print to same file? 如何比较它们并打印到同一文件?

Complex awk solution: 复杂的awk解决方案:

awk 'NF && NR>1 && $0!~/total:/{ 
         r=$2*$3; v=(v!="")? v"+"r : r; 
         if(r!=$4){ veg_er[$1]=r" instead of "$4 } 
         err_t+=$4; t+=r; $4=r 
     }
     $0~/total/ && err_t { 
         print $1,"("v")",$3,t; print "Error in calculations:"; 
         for(i in veg_er) { print "Veg total for "i" is wrong: it should be "veg_er[i] } 
         print "Overalltotal is wrong: It should be "t" instead of "err_t; next 
     }1' inputfile

The output: 输出:

kg  rate    total 
Tomato 4 50 200
potato 2 60 120
Beans 3 80 240

Overalltotal: (200+120+240) = 560
Error in calculations:
Veg total for Tomato is wrong: it should be 200 instead of 100
Overalltotal is wrong: It should be 560 instead of 460

Details: 细节:

  • NF && NR>1 && $0!~/total:/ - considering veg lines (excuding header and total lines) NF && NR>1 && $0!~/total:/ -考虑蔬菜行(不包括标题总行

  • r=$2*$3 - the result of product of the 2nd and 3rd fields r=$2*$3第二和第三字段的乘积结果

  • v=(v!="")? v"+"r : r v=(v!="")? v"+"r : r - concatenating resulting product values v=(v!="")? v"+"r : r连接结果乘积

  • veg_er - the array containing erroneous vegs info ( veg name, erroneous product value, and real product value) veg_er包含错误蔬菜信息( 蔬菜名称,错误产品值和实际产品值)的数组

  • err_t+=$4 - accumulating erroneous total value err_t+=$4累积错误的总价值

  • t+=r - accumulating real total value t+=r累计实际总价值

  • $0~/total/ && err_t - processing total line and error events $0~/total/ && err_t处理总行和错误事件

Input 输入项

akshay@db-3325:/tmp$ cat file
kg  rate    total
Tomato 4 50 100 
potato 2 60 120 
Beans 3 80 240

Output 输出量

akshay@db-3325:/tmp$ awk 'FNR>1{sum+= $2 * $3 }1;END{print "Total : "sum}' file
kg  rate    total
Tomato 4 50 100 
potato 2 60 120 
Beans 3 80 240
Total : 560

Explanation 说明

awk '                              # call awk
    FNR>1{                         # if no of lines of current file is greater than 1, 
                                   # then , this is to skip first row
            sum+= $2 * $3          # sum total which is product of value
                                   # in column2 and column3
     }1;                           # 1 at the end does default operation, 
                                   # that is print current record ( print $0 )
                                   # if you want to skip record being printed remove "1", so that script just prints total
     END{                          # end block
            print "Total : "sum    # print sum
     }
    ' file

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM