2015-10-01 46 views
1

我有一個* .xvg格式的文件。
它包含六列,每列500個數字。
除時間列(第一列)外,其他所有列都包含浮點數。使用awk或sed將行轉換爲列

我想要以相同的格式生成輸出文件,其中這些列被轉換爲行,每個數字以空格分隔。

我用C編寫了一個程序,對我來說工作正常,但我正在尋找一種使用awk或sed的替代方法,這將允許我執行相同的操作。

我對這些腳本語言絕對陌生。在以前提出的問題中,我找不到任何相關答案。所以,如果有人能幫助我完成這項任務,我將不勝感激。

輸入文件看起來像這樣: -

# This file was created Thu Oct 1 17:18:10 2015 
    # by the following command: 
    # /home/durba/gmx455/bin/mdrun -np 1 -deffnm md0 -v 
    # 
    @ title "dH/d\xl\f{}, \xD\f{}H" 
    @ xaxis label "Time (ps)" 
    @ yaxis label "(kJ/mol)" 
    @TYPE xy 
    @ subtitle "T = 200 (K), \xl\f{} = 0" 
    @ view 0.15, 0.15, 0.75, 0.85 
    @ legend on 
    @ legend box on 
    @ legend loctype view 
    @ legend 0.78, 0.8 
    @ legend length 2 
    @ s0 legend "dH/d\xl\f{} \xl\f{} 0" 
    @ s1 legend "\xD\f{}H \xl\f{} 0.05" 
    0 19.3191 1.16531 1.8 -447.07 -47.07 
    2 -447.072 -17.6454 1.5 -17.633 -1.33 
    4 -17.633 -0.446508 1.3 -75.455 -5.45 
    6 -75.4555 -2.83981 1.4 -28.724 -28.4 
    8 -28.7246 -0.884639 1.5 -41.877 -14.87 
    10 -41.8779 -1.45569 2.8 -43.685 -3.685 
    12 -43.6851 -1.4797 -3.1 -91.651 -91.651 
    14 -91.6515 -3.52492 -3.5 -61.135 -1.135 
    16 -61.1356 -2.30129 -3.2 -48.847 -48.47 

輸出文件應該是這樣的: -

# This file was created Thu Oct 1 17:18:10 2015 
    # by the following command: 
    # /home/durba/gmx455/bin/mdrun -np 1 -deffnm md0 -v 
    # 
    @ title "dH/d\xl\f{}, \xD\f{}H" 
    @ xaxis label "Time (ps)" 
    @ yaxis label "(kJ/mol)" 
    @TYPE xy 
    @ subtitle "T = 200 (K), \xl\f{} = 0" 
    @ view 0.15, 0.15, 0.75, 0.85 
    @ legend on 
    @ legend box on 
    @ legend loctype view 
    @ legend 0.78, 0.8 
    @ legend length 2 
    @ s0 legend "dH/d\xl\f{} \xl\f{} 0" 
    @ s1 legend "\xD\f{}H \xl\f{} 0.05" 
    0 2 4 6 8 10 12 
    19.3191 -447.072 -17.633 -17.633 -75.4555 -28.7246 -41.8779 -43.6851 -91.6515 -61.1356 
    1.16531 -17.6454 -0.446508 -2.83981 -0.884639 -1.45569 -1.4797 -3.52492 -2.30129 
    1.8 1.5 1.3 1.4 1.5 2.8 -3.1 -3.5 -3.2 
    -447.07 -17.633 -75.455 -28.724 -41.877 -43.685 -91.651 -61.135 -48.847 
    -47.07 -1.33 -5.45 -28.4 -14.87 -3.685 -91.651 -1.135 -48.47 

請注意,開始以 「#」 線和 「@」 應該是相同的在這兩個文件中。

+0

你能告訴我* .xvg文件的內容和預期的輸出嗎? – Kalanidhi

回答

1

這可能爲你工作(GNU SED):

sed -r 'H;$!d;x;:a;h;s/\n(\S+)[^\n]*/\1 /g;s/ $//p;g;s/\n\S+ ?/\n/g;ta;d' file 

啜食文件到保留空間(HS)刪除模式空間(PS),直到最終OF-文件條件得到滿足。在文件結尾交換PS的HS。將PS複製到HS,然後刪除第一個字段後面的所有字段,然後在第一個字段之後加上一個空格,然後全局。刪除最後一個空格並打印該行。然後回顧HS的線路副本並做相反的處理。如果任何替換成功,則重複該過程直到除了換行符之外都存在。刪除不需要的換行符。

自第一次回答原來的問題改變了。下面的新解決方案使用基本相同的方法迎合新問題:

sed -r '/^[0-9]/{s/ +/ /g;H};//!p;$!d;x;:a;h;s/\n(\S+)[^\n]*/\1 /g;s/ $//p;g;s/\n\S+ ?/\n/g;ta;d' file 
+0

這是一個相當令人印象深刻的使用sed。加一。 – John1024

3

回答原來的問題

讓我們看看這個測試文件:

$ cat file 
123 1.2 1.3 1.4 1.5 
124 2.2 2.3 2.4 2.5 
125 3.2 3.3 3.4 3.5 

要轉換列行:

$ awk '{for (i=1;i<=NF;i++)a[i,NR]=$i} END{for (i=1;i<=NF;i++) for (j=1;j<=NR;j++) printf "%s%s",a[i,j],(j==NR?ORS:OFS)}' file 
123 124 125 
1.2 2.2 3.2 
1.3 2.3 3.3 
1.4 2.4 3.4 
1.5 2.5 3.5 

它是如何工作

  • for (i=1;i<=NF;i++)a[i,NR]=$i

    當我們遍歷每一行時,我們將數值保存在數組a中。

  • END{for (i=1;i<=NF;i++) for (j=1;j<=NR;j++) printf "%s%s",a[i,j],(j==NR?ORS:OFS)}

    我們到達文件的結束以後,打印的每個值,隨後由所述輸出字段分隔符(OFS)如果我們在一條線或輸出記錄分隔符之中的(ORS )如果我們在行的末尾。

多層線路版

如果你喜歡你的代碼跨越了幾行:

awk ' 
{ 
    for (i=1;i<=NF;i++) 
    a[i,NR]=$i 
} 

END{ 
    for (i=1;i<=NF;i++) 
    for (j=1;j<=NR;j++) 
     printf "%s%s",a[i,j],(j==NR?ORS:OFS) 
} 
' file 

回答修訂問題

在修訂的問題,也有在線路以@#開始的文件的開頭不會被更改。在這種情況下:

$ awk '/^[@#]/{print;next}{k++; for (i=1;i<=NF;i++)a[i,k]=$i;} END{for (i=1;i<=NF;i++) for (j=1;j<=k;j++) printf "%s%s",a[i,j],(j==k?ORS:OFS)}' input 
# This file was created Thu Oct 1 17:18:10 2015 
# by the following command: 
# /home/durba/gmx455/bin/mdrun -np 1 -deffnm md0 -v 
# 
# 
# 
@ title "dH/d\xl\f{}, \xD\f{}H" 
@ xaxis label "Time (ps)" 
@ yaxis label "(kJ/mol)" 
@TYPE xy 
@ subtitle "T = 200 (K), \xl\f{} = 0" 
@ view 0.15, 0.15, 0.75, 0.85 
@ legend on 
@ legend box on 
@ legend loctype view 
@ legend 0.78, 0.8 
@ legend length 2 
@ s0 legend "dH/d\xl\f{} \xl\f{} 0" 
@ s1 legend "\xD\f{}H \xl\f{} 0.05" 
0 2 4 6 8 10 12 14 16 
19.3191 -447.072 -17.633 -75.4555 -28.7246 -41.8779 -43.6851 -91.6515 -61.1356 
1.16531 -17.6454 -0.446508 -2.83981 -0.884639 -1.45569 -1.4797 -3.52492 -2.30129 
1.8 1.5 1.3 1.4 1.5 2.8 -3.1 -3.5 -3.2 
-447.07 -17.633 -75.455 -28.724 -41.877 -43.685 -91.651 -61.135 -48.847 
-47.07 -1.33 -5.45 -28.4 -14.87 -3.685 -91.651 -1.135 -48.47 
+0

這太棒了。工作很好。 –

+0

還有一件事,如何在我的輸出文件中打印以「@」和「#」開頭的行。我想我可能不得不使用這個東西'awk'/^[@#] /' –

+0

@VikasDubey很高興它的工作。而且,是的,這是僅選擇以「@」或「#」開頭的行的正確命令。 – John1024