【问题标题】:Awk script to provide sum of certain columns in another column basis on criteriaawk 脚本根据标准提供另一列中某些列的总和
【发布时间】:2018-03-29 23:44:09
【问题描述】:

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

场景 1:

如果第一列中的值DocumentNo 出现一次并且 第二列 Line 的值为 10,然后我想对第 3、4、5 和 6 列(Taxablevalue,IGSTAmount,CGSTAm 和 SGSTAmo)求和,并放置/替换我们在八列中求和的这个值 @987654325 @:

示例数据:

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

情景 2:

如果我们在第一列 DocumentNo 中有多个具有相同值的行,在第二列 LineN 中有唯一值,那么我想将第 3、4、5 和 6 列的所有值相加(Taxablevalue,IGSTAmount,CGSTAm和SGSTAmo) 并放置/替换我们在每行的八列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||

预期输出场景一:

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

【问题讨论】:

  • 为此道歉..分享我在几分钟内尝试过的代码
  • 什么是分隔符?制表符?
  • @Andriy Makukha..分隔符是管道“|”
  • @kvantour..已经更新了我的问题..请检查
  • @as7951 还有几个小问题:输入是否在第 1 列中排序? cfr 列 1 和列 2 是否会出现相同的行?在情况 1 中,$2 是 10 重要吗?

标签: bash shell awk scripting


【解决方案1】:

我会分两次完成。

在第一遍中,我将创建一个字典 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

【讨论】:

  • 还需要考虑column2(lineN),因为column1的相同行需要column2(LineN)有唯一行,如果不需要报错。
  • @as7951,我用错误报告的变体更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-20
  • 2013-09-10
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多