代码之家  ›  专栏  ›  技术社区  ›  as7951

Awk脚本根据条件提供另一列中某些列的总和

  •  1
  • as7951  · 技术社区  · 7 年前

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

    场景1:

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

    示例数据 :

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

    Senario 2:

    如果在第一列中有多行具有相同的值 文件编号 和第二列中的唯一值 LineN ,那么我想对第3、4、5和6列的所有值求和( Taxablevalue、IGSTAmount、CGSTAm 斯格斯塔莫 )并放置/替换我们在八列中求和的值 发票价值 每行的。

    示例数据 :

    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 回复  |  直到 7 年前
        1
  •  1
  •   Andriy Makukha    7 年前

    我会在两次传球中完成。

    在第一次通过时,我会创建一个措辞 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列。如果你想解释这件事,你可能需要修改我的答案。


    为了确保所有对(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
    
    推荐文章