2011-12-26 109 views
0

所有列值的總和給出一個文件如:UNIX - 重複計數,計數和文件

sid|storeNo|latitude|longitude 
2|1|-28.03720000 
9|2 
10 
jgn352|1|-28.03720000 
9|2|fdjkjhn422-405 
|gfdjk39 

預期輸出:

sid|storeNo|latitude|longitude 
543240|6|-56.0744|0| 
6|5|3|0| 
5|3|2|0| 

我想返回值的計數在每列下,每列下不同值的計數,然後是每列下所有值的總和。但是,我的邏輯/語法肯定是錯的,任何幫助糾正它都會很棒!

代碼到目前爲止(在momemnt它返回無輸出):使用gawk

awk 'BEGIN{FS="|"} 
    NR==1{ 
      for(n = 1; n <= NF; n++) { 
       colname[n]=$n 
      } 
     } 
    NR>1 { #skips header 
    for(j=1;j<=NF;j++) 
    { 
     sum[j]+=$j 
     rawcount[j]++ 
     #distinctcount[j, arr[j]]=1 
    } 
    } 
    END{ 
    for(k=1;k<=NF;k++) 
    { 
    #for(i in distinctcount) 
    # distinctcount[k, i]++ 
    print colname[j]"|" 
print sum[j]"|" 
print rawcount[j]"|" 
print distinctcount[j]"|" 
    } 
    }' delimd2iffpipe.dat 
+0

你用各種腳本所做的所有事情最好用數據庫完成(例如sqlite,很容易編寫腳本)。 「總和」與您的樣本沒有很好的定義 - 您如何處理不是數字的條目?是否存在不存在的細胞?如果是這樣,他們所有不同或將3個空細胞計爲1在你的不同計數,或0? – Mat 2011-12-26 10:41:33

+0

@Mat -Sum將只添加數值,如果一個值中有任何非數字字符,那麼它將不會被包含在總和中。不存在的細胞不計算在內。即在不同的計數中爲0,因爲它沒有值。 – toop 2011-12-26 10:46:37

+0

你爲什麼試圖用文本文件和bash腳本來做到這一點?這絕對是使用DB後端(Mat推薦的sqlite或MySQL)和使用Python或Perl等編程語言來處理更好的方法。 – Drahkar 2011-12-26 10:49:18

回答

4

一種可能的解決方案。 該腳本使用多維數組,我認爲它只支持GNU版本。

BEGIN { 
     FS="|" 
} 

## Header. 
NR==1{ 
     ## Get this number to know later how many columns to print. 
     cols = NF; 

     ## Print header. 
     print 

     ## Read next record. 
     next 
} 

## Data. 
NR>1 { 
    ## For each column, get sum, count and distinct count, save values in arrays. 
    for(j=1;j<=NF;j++) 
    { 
     sum[j] += $j 
     rawcount[j]++ 
     distcount[j][$j]++ 
    } 
} 

END{ 
     print_line(sum) 
     print_line(rawcount) 

     ## To print distinct count, for each column we count how many values exist in 
     ## second dimension. 
     for (i = 1; i <= cols; i++) { 
       printf "%g|", length(distcount[i]) ? length(distcount[i]) : 0 
     } 
     print 
} 

func print_line(arr) 
{ 
     for (k = 1; k <= cols; k++) { 
       printf "%g|", arr[k] ? arr[k] : 0 
     } 
     print 

} 

運行腳本:

awk -f script.awk delimd2iffpipe.dat 

結果:

sid|storeNo|latitude|longitude 
543240|6|-56.0744|0| 
6|5|3|0| 
5|3|2|0| 

內容script.awk(含評論)的編輯:避免多維數組的方法。我用一個下標數組替代它。它的處理更復雜,但我希望它可以與所有版本的awk

這裏的代碼。我的機器中的結果與以前的腳本相同。

BEGIN { 
     FS="|" 
} 

## Header. 
NR==1{ 
     ## Get this number to know later how many columns to print. 
     cols = NF; 

     ## Print header. 
     print 

     ## Read next record. 
     next 
} 

## Data. 
NR>1 { 
     ## For each column, get sum, count and distinct count, save values in arrays. 
    for(j=1;j<=NF;j++) 
    { 
     sum[j] += $j 
     rawcount[j]++ 
     distcount[j, $j]++ 
    } 
} 

END{ 
     print_line(sum) 
     print_line(rawcount) 

     for (combined_index in distcount) { 
       split(combined_index, idx, SUBSEP) 
       dcount[ idx[1] ]++; 
     } 
     print_line(dcount) 
} 

func print_line(arr) 
{ 
     for (k = 1; k <= cols; k++) { 
       printf "%g|", arr[k] ? arr[k] : 0 
     } 
     print 

} 
+0

line:23:distcount [j] [$ j] ++ ^語法錯誤 – toop 2011-12-26 13:12:26

+0

@toop:增加了一個'awk'腳本,用下標數組代替'gawk'特定的多維數組。我希望它適用於您的版本。 – Birei 2011-12-26 13:54:09

+0

傳說!它不適用於我的awk,但適用於nawk。 – toop 2011-12-26 23:11:08