2015-10-08 77 views
0

我有一個輸出文件,其中包含下面顯示的一部分。awk讀取特定字符後的3個字符

================================================================================ 
             INPUT FILE 
================================================================================ 
NAME = t-Butylvinylidene-s.inp 
| 1> ! LPNO-CCSD cc-pVTZ cc-pVTZ/C UNO TIGHTSCF TIGHTOPT Grid6 NOFINALGrid NUMGRAD PAL4 
| 2> 
| 3> %geom Scan 
| 4> A 2 1 15 = 67, 71, 10 
| 5> end 
| 6> end 
| 7> 
| 8> *xyz 0 1 
| 9> 6  4.053878000 -18.527907000  -3.717354000 
| 10> 6  3.588474000 -18.874154000  -5.083237000 
| 11> 6  2.917226000 -19.112390000  -6.132425000 
| 12> 6  2.817703000 -18.178677000  -2.886206000 
| 13> 1  2.133454000 -19.025647000  -2.847879000 
| 14> 1  3.094894000 -17.913405000  -1.866801000 
| 15> 1  2.286657000 -17.336824000  -3.329174000 
| 16> 6  5.010397000 -17.327109000  -3.786851000 
| 17> 1  5.368223000 -17.071145000  -2.789879000 
| 18> 1  5.877217000 -17.555623000  -4.406951000 
| 19> 1  4.511903000 -16.455783000  -4.209438000 
| 20> 6  4.792242000 -19.727095000  -3.102721000 
| 21> 1  5.654756000 -20.005483000  -3.708269000 
| 22> 1  5.149078000 -19.479242000  -2.103325000 
| 23> 1  4.135842000 -20.593249000  -3.030303000 
| 24> 1  4.320782000 -19.183475000  -5.923829000 
| 25> * 
| 26> 
| 27>       ****END OF INPUT**** 
================================================================================ 

我想讀取第三個和最後3個字符。

| 4> A 2 1 15 = 67, 71, 10 

我有下面的代碼來做到這一點。

read -r -a scanopt <<< $(awk ' 
/INPUT FILE/ { input=1;} 
input && 
/geom Scan/ {getline;gsub(",",""); print $3,$8,$9,$10,"T";exit} 
' OFS="\t" "$path") 

輸入存在,以確保我找到合適的句子等 我的問題是有時候線可以是不同的,因此最後的3個數字,我需要將處於不同的位置!幾個例子是:

B 1 2 = 1.2, 2, 9 
D 4 8 9 5 = 50, 60, 12 

我需要第一次和最後3個字符,第一個具有恆定的位置,以便輕鬆,......但最後3,任何想法如何做到這一切我能想到的是一個有很多if的大循環。

我要考慮的另一個問題是,如果在輸入文件中有人會進入不同的方式信息如下:

%geom Scan A 2 1 15 = 67, 71, 10 
end 

%geom Scan 

A 2 1 15 = 67, 71, 10 
end 

,所以我真的需要處理逐字從我遇到%geom scan直到end。現在我正在逐行進行!

+0

腳本似乎要查找'INPUT FILE'和其他您的示例數據中未顯示的內容。請將您的腳本與您的示例數據相匹配,以便我們有機會看到您正在做的事情。可以在樣本輸入中添加更多行,或者(最好)從腳本中刪除多餘的材料。使用正確的腳本和示例數據,請顯示實際輸出和所需輸出。 –

+2

上面的輸出是什麼? '67,71,10'?尋找'/ INPUT FILE /'然後'/%geom /'然後'/ = /'(可能與'%geom'在同一行。然後循環尋找'='的字段(或者用'FS =「=」'或類似的方法重新分割該行)。 –

+0

我在想它,但會是一個非常髒的代碼。 –

回答

3

我想你是指第三和最後三個字段?

awk '{print $3, $(NF-2), $(NF-1), $NF}' 

會做到這一點。

的其他要求,我認爲這應該工作

awk '  /end/{f=0} 
    /%geom Scan/{f=1;sub(/^.*%geom Scan/,"")} 
     f&&NF>3{print $3,$(NF-2),$(NF-1),$NF}' 

更新修剪現場計數​​的標題行和保護。

+0

請檢查它打印錯誤數據的代碼。 –

+0

它是'|之後的第一個4>'編號。並且您的代碼在第一行中打印兩次,然後用我想要的打印另一行。 –

+0

第一到第三。 – karakfa

2

關鍵是要知道你可以依靠99.9%以及你在輸入中不能做什麼。同時也知道awk允許從「結尾」領取字段。

在我看來,你總是可以指望感興趣的線條(只有那些線條)包含模式[數字] [可選空格] [等號]。如果這是真的,這應該工作:

awk '/[0-9]\s*=/{print $3, $(NF-2), $(NF-1), $NF, "T"; exit}' 

對於你的第二個情況,你會上面的一個前添加第二圖案(先抓住它):

awk '/%geom Scan .*=/{print $5, $(NF-2), $(NF-1), $NF, "T"; exit} 
    /[0-9]\s*=/{print $3, $(NF-2), $(NF-1), $NF, "T"; exit}'