2017-05-22 45 views
0

我有一個4列文件(input.file)與頭:請在弦數數學(和文本使用awk解析)

something1 something2 A B 

,然後用相同的格式很多4列行(例如, ):

ID_00001 1 0 0 
ID_00002 0 1 0 
ID_00003 1 0 0 
ID_00004 0 0 1 
ID_00005 0 1 0 
ID_00006 0 1 0 
ID_00007 0 0 0 
ID_00008 1 0 0 

其中, 「1 0 0」 代表 「AA」 的, 「0 1 0」 是指 「AB」 和 「0 0 1」 表示 「BB」

首先,我喜歡創建第5列來識別這些表示:

ID_00001 1 0 0 AA 
ID_00002 0 1 0 AB 
ID_00003 1 0 0 AA 
ID_00004 0 0 1 BB 
ID_00005 0 1 0 AB 
ID_00006 0 1 0 AB 
ID_00007 0 0 0 no data 
ID_00008 1 0 0 AA 

注意的是,A和B的需要從第3和標題行的4解析,因爲他們並不總是A和B.

接下來,我想「做數學」上用於(新)柱5計數如下:

(2BB + AB)/2(AA + AB + BB) 

使用的例子中,數學會給:

(2(1)+ 3)/ 2(3 + 3 + 1)= 5/14 = 0.357

我想追加到所需的輸出文件(output.file)結束:

ID_00001 1 0 0 AA 
ID_00002 0 1 0 AB 
ID_00003 1 0 0 AA 
ID_00004 0 0 1 BB 
ID_00005 0 1 0 AB 
ID_00006 0 1 0 AB 
ID_00007 0 0 0 no data 
ID_00008 1 0 0 AA 

B_freq = 0.357 

到目前爲止,我有這樣的:

awk '{ if ($2 = 1) {print $0, $5="AA"} \ 
else if($3 = 1) {print $0, $5="AB"} \ 
else if($4 = 1) {print $0, $5="BB"} \ 
else {print$0, $5="no data"}}' input.file > output.file 

顯然,我沒能圖瞭解如何解析第1行的信息(標題行,編輯出「第1列」),更不用說數學了。

謝謝你們!

+0

'...如何解析從塔1 ...'的信息? – karakfa

+0

意思是第1行(標題行),對於 – gobot6

+0

更爲具體,我不能夠(例如)解析標題行第3列中的「A」,並將它(兩次)放入後續「 1 0 0「行。 – gobot6

回答

1

更結構化的方法......

NR==1 {a["100"]=$3$3; a["010"]=$3$4; a["001"]=$4$4; print; next} 
     {k=$2$3$4; 
     print $0, (k in a)?a[k]:"no data"; 
     c[k]++} 
END {printf "\nB freq = %.3f\n", 
     (2*c["001"]+c["010"])/2/(c["100"]+c["010"]+c["001"])} 

UPDATE 對於非二進制數據,你可以按照同樣的邏輯與一些預處理。這樣的事情應該在主塊的工作:

for(i=2;i<5;i++) v[i]=(($i-0.9)^2<=0.1^2)?1:0; 
k=v[2] v[3] v[4]; 
... 

這裏的值在一個量化爲範圍[0.8,1],否則爲零。

要捕獲「B」或替代在第一塊設置h=$4並使用它作爲printf "\n%s freq...",h,(2*c...

+0

您的回答在提問時完美解決了問題。如何更改代碼以允許輸入文件主體中每列第2,3和4列的值範圍(具體來說,如果我想接受範圍> = 0.8 && <= 1(即0.8 -1)作爲A或B的可接受呼叫)?例如,如果實際行號是0.84 0.15 0.01,我仍然需要AA呼叫(而不是沒有數據)。請讓我知道我是否應該從頭開始創建一個新問題。(我認爲我可以自己調整範圍,但是你的答案超出了我的編輯能力)。 – gobot6

+0

請測試更新,但我還沒有嘗試... – karakfa

+0

我在原始腳本中的「END {」和「printf」之間放置了額外的(預處理)腳本。與原始腳本相比,我生成了一個有效但未更改的輸出。我不確定是否將其他腳本放在錯誤的位置或者它不起作用。謝謝。 – gobot6