2012-03-17 82 views
1

我想使用awk讀取格式化文件。內容如下所示:使用awk格式化讀取

1PS1  A1 1 11.197 5.497 7.783 
    1PS1  A1 1 11.189 5.846 7.700 
    . 
    . 
    . 

以下的C格式,這些線是按以下格式 「%5D%5S%5S%5D%8.3f%.3f%8.3f」 其中,前5位是整數(1),接下來的5個位置是字符(PS1),接下來的5個位置是字符(A1),接下來的5個位置是整數(1),接下來的24個位置分成3列8個位置,帶有3個小數點浮點數。

我一直在用的只是用「$ 1,$ 2,$ 3」來調用這些由行分隔的行。例如,

cat test.gro | awk 'BEGIN{i=0} {MolID[i]=$1; id[i]=$2; num[i]=$3; x[i]=$4; 
y[i]=$5; z[i]=$6; i++} END { ...} >test1.gro 

但我遇到了一些問題,這一點,我現在想如上面所討論的格式化方式來閱讀這些文件。

任何想法如何做到這一點?

回答

2

看看你的示例輸入,看起來格式字符串實際上是"%5d%-5s%5s%5d%8.3f%.3f%8.3f",第一個字符串字段是左對齊的。這太糟糕了awk沒有一個scanf()功能,但你可以用幾個substr()電話讓您的數據

awk -v OFS=: ' 
    { 
    a=substr($0,1,5) 
    b=substr($0,6,5) 
    c=substr($0,11,5) 
    d=substr($0,16,5) 
    e=substr($0,21,8) 
    f=substr($0,29,8) 
    g=substr($0,37,8) 
    print a,b,c,d,e,f,g 
    } 
' 

輸出

1:PS1 : A1: 1: 11.197: 5.497: 7.783 
    1:PS1 : A1: 1: 11.189: 5.846: 7.700 

如果你有GNU AWK,您可以使用FIELDWIDTHS變量像這樣:

gawk -v FIELDWIDTHS="5 5 5 5 8 8 8" -v OFS=: '{print $1, $2, $3, $4, $5, $6, $7}' 

還輸出

1:PS1 : A1: 1: 11.197: 5.497: 7.783 
    1:PS1 : A1: 1: 11.189: 5.846: 7.700 
1

你從來沒有說過你認爲哪個字段應該有什麼數字,所以我想清楚地知道awk是如何工作的(你選擇明確地在輸出格式字符串字段中調用空格會讓我擔心一點點,你可能對此有不同的想法,比awk)。

從手冊頁:

輸入線通常是由空格, 分隔的字段的或由正則表達式FS。這些字段表示爲$ 1,$ 2,...,而 $ 0表示整行。如果FS爲空,則輸入行將被拆分爲每個字符一個字段,即 。

請注意,輸入行中的空格未指定字段編號,並且該順序空白符被視爲單個字段分隔符。在命令行

echo "1 2 3 4" | awk '{print "1:" $1 "\t2:" $2 "\t3:" $3 "\t4:" $4}' 

你可以像進行測試。


所有這一切都假定你沒有diddles的FS變量,當然。

+0

謝謝。其實,我忘了我可以用gawk使用FIELDWIDTHS選項。 – Greg 2012-03-17 18:56:00

+0

@Greg:如果是'FIELDWIDTHS'解決了你的問題,你不應該接受格倫的答案嗎? – dmckee 2012-03-17 19:39:07

+0

謝謝dmckee,進行更正。 – Greg 2012-03-17 21:05:26