2014-09-05 64 views
0

想打印基於第2列&第4列,行項目數,第3列,第一列的唯一值awk來計數總和和獨特的提高指揮 - 缺點:

的總和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

如果輸出的順序是那麼重要的,你可以這樣做:

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的數組索引的數組。第二個僅限於GNU awk

+1

@EdMorton是的好建議。使用由'SUBSEP'分隔的組合鍵總是爲我完成了這項工作,所以我從來沒有真正使用'awk'中的真正的多維數組。我想我應該開始閱讀它。 ':)' – 2014-09-05 16:12:16

+1

二維數組對於許多常見應用程序非常有用。一個應用程序,例如在一個僞二維數組的多行上讀取一個公共密鑰的值:'a [$ 1] =($ 1在$ a [$ 1] RS:「」)$ 2; ... END {for(key in a){split(a [key],tmp,RS); for(i = 1; i in tmp; i ++){val = tmp [i]; ('key',val}}}'對於真2維數組變得更簡單:'a [$ 1] [$ 2]; ... END {for(key in a)for(val in [key])print key, VAL}'。在那裏可能有語法錯誤或2,但你明白了。 – 2014-09-05 16:18:14

+0

讓我們[在聊天中繼續討論](http://chat.stackoverflow.com/rooms/60716/discussion-between-avn-and-jaypal)。 – VNA 2014-09-05 17:21:06

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 
+0

非常感謝Scrutinizer,簡直棒極了! – VNA 2014-09-05 16:59:15

+0

謝謝@AVN,很高興聽到:) .. – Scrutinizer 2014-09-05 17:27:55