awk到Count Sum和Unique改进命令 - Con:

时间:2014-09-05 15:01:15

标签: awk

想要根据第2栏和第2栏打印第4列,订单项数量,第3列总和以及第1列的唯一值

Input.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

寻找你的建议!!!

2 个答案:

答案 0 :(得分:2)

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

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块中,我们遍历订单并打印这些数组的输出。

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

答案 1 :(得分:1)

尝试:

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