【问题标题】:awk to Count Sum and Unique improve command - Con:awk to Count Sum and Unique 改进命令 - 缺点:
【发布时间】:2014-09-06 01:26:16
【问题描述】:

希望根据第 2 列和第 4 列、行项目数、第 3 列的总和和第一列的唯一值进行打印

输入.csv

abc,xx,5,Jan-2014
abc,yy,10,Jan-2014
def,xx,15,Jan-2014
def,yy,20,Jan-2014
abc,xx,5,Jan-2014
abc,yy,10,Jan-2014
def,xx,15,Jan-2014
def,yy,20,Jan-2014
ghi,zz,10,Jan-2014
abc,xx,5,Feb-2014
abc,yy,10,Feb-2014
def,xx,15,Feb-2014
def,yy,20,Feb-2014
abc,xx,5,Feb-2014
abc,yy,10,Feb-2014
def,xx,15,Feb-2014
def,yy,20,Feb-2014
ghi,zz,10,Feb-2014

尝试#1:

awk '
BEGIN { FS = OFS = "," }
{ keys=$2","$4;keys[$2][$4]++;  sum[$2]+=$3 } !seen[$1,$2,$4]++ { count[$2]++ }
END   { for(key in keys) print key, keys[key], sum[key], count[key] }
' Input.csv

尝试#2:

awk '
BEGIN { FS = OFS = "," }
{ keys=[$2][$4];keys[$2][$4]++;  sum[$2]+=$3 } !seen[$1,$2,$4]++ { count[$2]++ }
END   { for(key in keys) print key, keys[key], sum[key], count[key] }
' Input.csv

尝试#3:

awk '
BEGIN { FS = OFS = "," }
{ keys=[$2,$4];keys[$2][$4]++;  sum[$2]+=$3 } !seen[$1,$2,$4]++ { count[$2]++ }
END   { for(key in keys) print key, keys[key], sum[key], count[key] }
' Input.csv

期望的输出:

xx,Jan-2014,4,40,2
yy,Jan-2014,4,60,2
zz,Jan-2014,1,10,1
xx,Feb-2014,4,40,2
yy,Feb-2014,4,60,2
zz,Feb-2014,1,10,1

寻求您的建议!!!

【问题讨论】:

    标签: awk


    【解决方案1】:

    如果输出顺序很关键,那么你可以这样做:

    awk '
    BEGIN { SUBSEP = FS = OFS = "," }
    !seen[$1,$2,$4]++ { count[$2,$4]++ } 
    !patt[$2,$4]++    { order[++nr] = $2 FS $4 }
    { values[$2,$4]++; sum[$2,$4]+=$3 } 
    END { 
        for (idx=1; idx<=nr; idx++) 
            print order[idx], values[order[idx]], sum[order[idx]], count[order[idx]] 
    }' file 
    xx,Jan-2014,4,40,2
    yy,Jan-2014,4,60,2
    zz,Jan-2014,1,10,1
    xx,Feb-2014,4,40,2
    yy,Feb-2014,4,60,2
    zz,Feb-2014,1,10,1
    

    我们将输入和输出字段分隔符设置为,SUBSEP 设置为 , 以防止使用 , 作为数组的键分隔符。 !seen[$1,$2,$4]++ 记住基于指定的 3 列的模式并保留一个计数器。 !patt[$2,$4]++ 帮助我们记住订单。 values[$2,$4]++sum[$2,$4]+=$3 分别根据第二列和第四列及其总和跟踪唯一模式的计数。

    END 块中,我们遍历订单并打印这些数组的输出。

    注意: 正如 cmets 中所建议的,查看您尝试使用 a[$1,$2]a[$1][$2] 时,您应该知道它们是完全不同的。 a[$1,$2] 一个由 1 SUBSEP 2 索引的字符串数组,其中 a[1][2] 是一个由 2 索引的数组中的 1 索引的数组。第二个是 GNU awk

    【讨论】:

    • @EdMorton 好的建议。使用由SUBSEP 分隔的复合键总是为我完成工作,所以我从未真正使用过awk 中真正的多维数组。我想我应该开始阅读它。 :)
    • 二维数组对于许多常见应用非常有用。使用伪二维数组:a[$1] = ($1 in a ? a[$1] RS : "") $2;...END{for (key in a) { split(a[key],tmp,RS); for (i=1;i in tmp; i++) { val=tmp[i]; print key, val } } } 读取多行公共键的 val 等应用程序使用真正的二维数组:a[$1][$2];...END{for (key in a) for (val in a[key]) print key, val} 变得更加简单。那里可能有一个或 2 个语法错误,但你明白了。
    【解决方案2】:

    试试:

    awk '{i=$2 FS $4; S[i]+=$3} !A[$1,i]++{C[i]++} END{for(i in S) print i, S[i], C[i]}' FS=, OFS=, file
    

    多行:

    awk '
      BEGIN {
        FS=OFS=","
      }
    
      {
        idx=$2 FS $4
        Sum[idx]+=$3
      }
    
      !Seen[$1,idx]++ {
        Count[idx]++
      }
    
      END {
        for(idx in Sum) print idx, Sum[idx], Count[idx]
      }
    ' file
    

    输出:

    xx,Feb-2014,40,2
    zz,Feb-2014,10,1
    yy,Feb-2014,60,2
    yy,Jan-2014,60,2
    xx,Jan-2014,40,2
    zz,Jan-2014,10,1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-11
      • 1970-01-01
      • 2022-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-02
      • 2012-12-08
      相关资源
      最近更新 更多