2016-12-03 84 views
0

我需要解析用不同參數運行的化學程序的輸出,並以特定格式組合感興趣的信息。awk或sed命令解析來自多個文件的數據並使用特定格式將它們組合

從程序中的每個輸出文件看起來如下表所示,它在特定pH給出質子化和未質子化的物種(殘基)的人口(在這裏它是在pH = 0):

Residue Number  State 0  State 1  State 2  State 3  State 4 
----------------------------------------------------------------------------------- 
Residue: GL4 7 0.000410 (0) 0.453512 (1) 0.004275 (1) 0.535908 (1) 0.005895 (1) 
Residue: HIP 15 0.900000 (2) 0.080000 (1) 0.020000 (1) 
Residue: AS4 18 0.010085 (0) 0.486042 (1) 0.004335 (1) 0.495922 (1) 0.003615 (1) 
Residue: GL4 35 0.000000 (0) 0.581343 (1) 0.000360 (1) 0.368002 (1) 0.050295 (1) 
Residue: AS4 48 0.022640 (0) 0.520073 (1) 0.018440 (1) 0.425152 (1) 0.013695 (1) 
Residue: AS4 52 0.038725 (0) 0.517533 (1) 0.113676 (1) 0.280601 (1) 0.049465 (1) 
Residue: AS4 66 1.000000 (0) 0.000000 (1) 0.000000 (1) 0.000000 (1) 0.000000 (1) 
Residue: AS4 87 0.004295 (0) 0.439747 (1) 0.010535 (1) 0.524678 (1) 0.020745 (1) 
Residue: AS4 101 0.000105 (0) 0.504673 (1) 0.013110 (1) 0.478517 (1) 0.003595 (1) 
Residue: AS4 119 0.014240 (0) 0.488767 (1) 0.007100 (1) 0.483272 (1) 0.006620 (1) 

我每個pH都有一個這樣的文件(所有文件都有完全相同的殘基和狀態,只有總體變化)。現在我想提取所有殘基的去質子化部分。去質子化的部分對應於在其數目後具有(0)的羣體:例如,在pH = 0時GL4 7爲0.000410(對應於狀態0),對於AS4 66爲1.00000。事實上,對於所有殘餘物,其狀態爲0,除了HIP15以外:在這種情況下,去質子化部分用(1)表示並對應於狀態1和2.在上面的例子中,它是0.080000 + 0.020000 = 0.1。

然後我需要從不同的文件此信息組合成一個單一的文件,該文件是這樣的:

#  pH  GLU7 HIS15 ASP18 GLU35 ASP48 ASP52 ASP66 ASP87 ASP101 ASP119 
    0.000 0.000 0.100 0.010 0.000 0.023 0.039 1.000 0.004 0.000 0.014 
    1.000 0.006 0.140 0.098 0.000 0.276 0.312 1.000 0.015 0.002 0.069 

每一列對應於殘餘物中,每行的pH(即,從一個信息單個文件,這裏我只顯示來自兩個文件的信息)。

我試圖想出一些awk單線程,但我是初學者,我不知道如何繼續。其實,我不知道awk是否是這份工作的最佳工具。也許sed和grep或python會更好。 我將需要做幾種不同的輸出(但它們看起來都一樣,儘管殘基會改變),這樣的解析有幾種方式,所以我想有一種方法可以實現這種自動化,但具有一定的靈活性。

請不要猶豫,如果您有任何建議或意見,我真的很感激,如果你能幫我分揀這個問題。

非常感謝提前!

+0

'awk'不是一個好的解決方案,因爲它一次只能處理一個文件,並且不能合併文件。我推薦使用Python'pandas''DataFrame's。 – DyZ

+0

爲什麼用'(1)'表示'HIP 15'的去質子化分數?去質子化分數是那些以_minimum_數字作爲指標的狀態的總和? – mhawke

+0

@mhawke,的確,這是一個很好的觀點:他去質量分數是以最小數量作爲指標的那些州的總和。這可以用來以某種方式提取感興趣的信息嗎? – ejl62

回答

0

您可以使用for循環將所有文件捕獲到文件中,並使用Stackoverflow中的以前解決方案將該行轉置爲列。

An efficient way to transpose a file in Bash

+0

謝謝,但它不是一個簡單的轉置,我需要從原始文件中提取特定位 – ejl62

0

這不是完全清楚你想要什麼,但Python的分裂功能也可能會被使用到你的。如果所謂的不帶任何參數,它分裂基礎上的空間(整理多個空格轉換爲一個)

所以這條線,例如,

Residue: GL4 7 0.000410 (0) 0.453512 (1) 0.004275 (1) 0.535908 (1) 0.005895 (1) 

可以拆分這樣,

a = 'Residue: GL4 7 0.000410 (0) 0.453512 (1) 0.004275 (1) 0.535908 (1) 0.005895 (1)' 
l = a.split() 
print l 

['Residue:', 'GL4', '7', '0.000410', '(0)', '0.453512', '(1)', '0.004275', '(1)', '0.535908', '(1)', '0.005895', '(1)'] 

你可以然後訪問你想要的值並對它們進行處理。對字符串調用float和int(例如float('0.00410')應該將它們轉換爲數字。對於'(1)',可以執行int('(1)'[1:-1])

0

這個awk腳本應該讓你開始,爲了得到所需的輸出,你必須用相應的pH值替換文件名,並且省略了不包含零狀態的行,因爲你沒有指定要做什麼和那些。

/^ Residue/ || /^-----/ { next; } 

{ 
    filenames[FILENAME] = 1; 
    columns[$2 " " $3] = 1; 
    for (i = 5; i <= NF; i = i + 2) { 
     if ($i == "(0)") { 
      data[$2 " " $3, FILENAME] = $(i-1); 
     } 
    } 
} 

END { 
    printf("%10s", "filename"); 
    for (col in columns) { 
     printf("%10s", col); 
    } 
    print ""; 
    for (filename in filenames) { 
     printf("%10s", filename); 
     for (col in columns) { 
      printf("%10s", data[col, filename]); 
     } 
     print ""; 
    } 
} 
相關問題