Awk脚本,根据条件

时间:2018-03-29 11:26:34

标签: bash shell awk scripting

需要你的帮助, 有一个文件,数据如下所示。 以下两种情况的数据仅出现在1(单个)文件中,并且只在可能的情况下希望预期输出在同一文件中

情景1:

如果第一列DocumentNo中的值出现一次,那么  第二列Line的值为10,然后我想将第3,4,5和6列(Taxablevalue,IGSTAmount,CGSTAmSGSTAmo)相加并放置/替换我们已经求和的值在八列Invoicevalue中:

示例数据

DocumentNo|Line|Taxablevalue|IGSTAmount|CGSTAm|SGSTAmo|OthTa|InvoiceValue
262881894|10|10000|0|900|900||  

Senario 2:

如果我们在第一列DocumentNo中有多个具有相同值的行,而在第二列LineN中有唯一值,那么我想将第3,4,5和6列的所有值相加(Taxablevalue,IGSTAmount,CGSTAmSGSTAmo)并放置/替换我们在每行的{8}列Invoicevalue中求和的值。

示例数据

DocumentNo|LineN|Taxablevalue|IGSTAmo|CGSTAmo|SGSTAmou|OthTa|InvoValue
262881894|10|10000|0|900|900||              
262881894|20|15000|0|1350|1350||            
262881894|30|20000|0|1800|1800||

预期输出情景1:

DocumentNo|Line|Taxablevalue|IGSTAmount|CGSTAm|SGSTAmo|OthTa|InvoiceValue
 262881894|10|10000|0|900|900||11800

预期输出情景2:

  

发票金额= 10000 + 15000 + 20000 + 0 + 0 + 0 + 900 + 1350 + 1800 + 900 + 1350 + 1800 =   53100

DocumentNo|LineN|Taxablevalue|IGSTAmo|CGSTAmo|SGSTAmou|OthTa|InvoValue
  262881894|10|10000|0|900|900||53100  
  262881894|20|15000|0|1350|1350||53100 
  262881894|30|20000|0|1800|1800||53100

以下是尝试过的代码,但无法弄清楚如何在lastcolumn中添加值(InvoValue)

awk '{a[$1]+=$3;b[$1]+=$4;c[$1]+=$5;d[$1]+=$6;}
      END {for(i in a) { print " " a[i] " " b[i] " " c[i] " " d[i];}}' File

以下是我收到的代码输出。可悲的是,它不符合我的预期输出:

0 0 0 0

1 个答案:

答案 0 :(得分:1)

我会两次通过。

在第一遍中,我会创建一个dictinary s,它将保留任何特定文档编号的第3,4,5和6列的总和。

在第二遍中,我将替换InvoValue列中的值。

以下是输入data.txt的示例:

DocumentNo|LineN|Taxablevalue|IGSTAmo|CGSTAmo|SGSTAmou|OthTa|InvoValue
262881894|10|10000|0|900|900||
262881894|20|15000|0|1350|1350||
262881894|30|20000|0|1800|1800||
262881895|10|10000|0|900|900||

这是命令:

gawk 'BEGIN { OFS=FS="|" } NR == FNR { s[$1] += $3+$4+$5+$6; next } FNR!=1 { $8 = s[$1] } 1;' data.txt data.txt

这是输出:

DocumentNo|LineN|Taxablevalue|IGSTAmo|CGSTAmo|SGSTAmou|OthTa|InvoValue
262881894|10|10000|0|900|900||53100
262881894|20|15000|0|1350|1350||53100
262881894|30|20000|0|1800|1800||53100
262881895|10|10000|0|900|900||11800

请注意,我完全忽略了第2列。如果您想要考虑LineN,则可能需要修改我的答案。

要确保所有对(DocumentNo,LineN)都是唯一的并且只出现一次,您可以添加此错误检测:

if (met[$1 FS $2]) print "ERROR: " $1 " " $2; 
met[$1 FS $2] = 1;

因此,带错误检测的更新命令将是:

gawk 'BEGIN { OFS=FS="|" } NR == FNR { if (met[$1 FS $2]) print "ERROR: " $1 " " $2; met[$1 FS $2] = 1; s[$1] += $3+$4+$5+$6; next } FNR!=1 { $8 = s[$1] } 1;' data.txt data.txt