2013-02-05 30 views
1

我有一個由單個單元1s,2s和3s組成的多列文件。每列中有很多單元重複,有時會從一個單元切換到另一個單元。我想要統計每個列上發生這種切換的次數。例如,在第1列中,開關從1變爲2,從3變爲1,因此有3個開關,輸出應爲3.在第二列中,整列爲2,所以變化爲0,輸出爲0如何在表的每一列上循環awk命令並輸出到單個輸出文件?

我的輸入文件有4000列,所以不可能手工完成。該文件是空格分隔的。

例如:

輸入:

1 2 3 1 2 
1 2 2 1 3 
1 2 3 1 2 
2 2 2 1 2 
2 2 2 1 2 ...... 
3 2 2 1 2 
3 2 2 1 1 
1 2 2 1 1 
1 2 2 1 2 
1 2 2 1 1 

希望的輸出:

3 ## column 1 switch times 
0 ## column 2 switch times 
3 ..... 
0  
5  

我用:

awk '{print $1}' <inputfile> | uniq | wc -l 
awk '{print $2}' <inputfile> | uniq | wc -l 
awk '{print $3}' <inputfile> | uniq | wc -l 
.... 

這一次執行一列。它會給我第一列的輸出「4」,稍後我會計算4-1 = 3來獲得我想要的輸出。但是有沒有辦法將這個awk命令寫入一個循環並在每一列上執行並輸出到一個文件?

謝謝!

回答

2

awk告訴你在變量NF的給定行中有多少個字段,所以你可以創建兩個數組來跟蹤你所需要的信息。一個數組將保留給定列中最後一行的值。另一個將計算給定列中的開關數量。您還將記錄最大列數(並將新列的計數設置爲零,以便在該列的開關數爲0時將它們正確地打印在輸出結尾處)。您還將確保不計算從空字符串到非空字符串的轉換 - 這是第一次遇到列時發生的情況。

如果實際上文件的列數一致,那隻會影響第一行數據。如果後面的行實際上比第一行有更多的列,那麼它會添加它們。如果一個列停止出現一段時間,我認爲它應該從它停止的地方恢復(就像缺失的列與以前一樣)。你可以決定不同的算法;這可以算作兩個轉換(從數字到空白,從空白到數字),如果是這樣的話,你必須修改計數代碼,或者更明智的是,你可以決定不規則數量的列是不允許的,在這種情況下,如果當前行中的列數與上一行中的列數不相同,那麼您可以提前退出(注意空白行,或者它們也被取消了嗎?)。

而且您不會嘗試寫入整個程序在一條線上,因爲它將是不可理解的,而且它確實沒有必要。

awk '{ if (NF > maxNF) 
     { 
      for (i = maxNF + 1; i <= NF; i++) 
       count[i] = 0; 
      maxNF = NF; 
     } 
     for (i = 1; i <= NF; i++) 
     { 
      if (col[i] != "" && $i != col[i]) 
       count[i]++; 
      col[i] = $i; 
     } 
    } 
    END { 
     for (i = 1; i <= maxNF; i++) 
      print count[i]; 
    }' data-file-with-4000-columns 

鑑於示例數據(移除了點),從腳本輸出的要求:

3 
0 
3 
0 
5 

這與鋸齒狀行替代數據文件:

1 2 3 1 2 
1 2 2 1 3 
1 2 3 1 2 
2 2 2 1 2 
2 2 2 1 2 1 1 1 
3 2 2 1 2 2 1 
3 2 2 1 1 
1 2 2 1 1 2 2 1 
1 2 2 1 
1 2 2 1 1 3 

產生輸出:

3 
0 
3 
0 
3 
2 
1 
0 

根據我制定的規則,這是正確的 - 但如果您決定要使用不同的規則來涵蓋數據,則最終可能會得到不同的答案。

如果在最後一個循環中使用了printf("%d\n", count[i]);,則不需要在循環中將計數值設置爲零。你支付你的錢,並採取你的選擇。

+0

謝謝喬納森爲您的全面答案!我非常感謝你的幫助! – user1687130

2

使用一個循環,並保持一個陣列的每個列當前值和另一個數組爲相應計數

awk '{for(i=0;i<5;i++) if(c[i]!=$(i+1)) {c[i]=$(i+1); t[i]++}} END{for(i=0;i<5;i++)print t[i]-1}' filename 

注意,這個假設列的值不爲零。如果碰巧有零值,那麼只需將數組c初始化爲一些不會出現在文件中的唯一值。

0

編碼爲便於查看,SaveColx,CountColx應該是數組。我會在結果中至少打印列號本身至少用於檢查:-)

BEGIN { 
    SaveCol1 = " " 
    CountCol1 = 0 
    CountCol2 = 0 
    CountCol3 = 0 
    CountCol4 = 0 
    CountCol5 = 0 
} 
{ 
if (SaveCol1 == " ") { 
    SaveCol1 = $1 
    SaveCol2 = $2 
    SaveCol3 = $3 
    SaveCol4 = $4 
    SaveCol5 = $5 
    next 
    } 
if ($1 != SaveCol1) { 
    CountCol1++ 
    SaveCol1 = $1 
    } 
if ($2 != SaveCol2) { 
    CountCol2++ 
    SaveCol2 = $2 
    } 
if ($3 != SaveCol3) { 
    CountCol3++ 
    SaveCol3 = $3 
    } 
if ($4 != SaveCol4) { 
    CountCol4++ 
    SaveCol4 = $4 
    } 
if ($5 != SaveCol5) { 
    CountCol5++ 
    SaveCol5 = $5 
    } 
} 
END { 
    print CountCol1 
    print CountCol2 
    print CountCol3 
    print CountCol4 
    print CountCol5 
} 
+0

這個問題指出實際數據中有4000列。我不認爲你的解決方案很容易擴展到4000列。 –

+0

:-)這就是這個位「SaveColx,CountColx應該是數組」的地方。 –

相關問題