2015-03-19 151 views
0

如果我們有以下的CSV文件,我們只希望得到$ 9的「DELTA能源燕鷗」的一部分,不包括開始與「框架」行awk的未來和模式匹配

Ligand Energy Terms 
Frame #,VDWAALS,EEL,EGB,ESURF,ESCF,G gas,G solv,TOTAL 
0,0.0,0.0,-37.2465,2.70257904,98.8916,0.0,-34.54392096,64.34767904 
1,0.0,0.0,-33.1958,2.71419624,80.6403,0.0,-30.48160376,50.15869624 

DELTA Energy Terms 
Frame #,VDWAALS,EEL,EGB,ESURF,ESCF,DELTA G gas,DELTA G solv,DELTA TOTAL 
0,-43.3713,0.0,44.4036,-5.24443392,-27.4605,-43.3713,39.15916608,-31.67263392 
1,-43.7597,0.0,37.343,-5.1764544,-23.3471,-43.7597,32.1665456,-34.9402544 
2,-42.5618,0.0,44.0748,-5.2738956,-26.6719,-42.5618,38.8009044,-30.4327956 
3,-43.1034,0.0,41.3681,-5.25029544,-27.1501,-43.1034,36.11780456,-34.13569544 

所需的輸出:

-31.6726 
-34.9402 
-30.4327 
-34.1356 

以下嘗試將打印出所有9美元,包括「配體能量術語」部分中的9美元。

awk -F, '$1 ~ /DELTA Energy Terms/ {next} $1 ~ /Frame/ {next} {printf("%24.4f\n",$9)}' 

awk -F, '$1 ~ /DELTA Energy Terms/ {next} {printf("%24.4f\n",$9)}' 

任何大師能啓發嗎?

回答

1

下應該做的伎倆

awk -F, '/^DELTA/ {capture=1} /Energy Terms$/ {next} /^Frame/ {next} (capture) {print $9}' 

我用capture標誌來控制單個記錄是否應該被抓獲。默認capture爲零。當DELTA Energy Terms行被解析時,我開始捕獲。我跳過以Energy Terms結尾或以Frame開頭的行。否則,如果我們「捕捉」,那麼我就帶出第九個元素。

如果你經常使用這個劇本,我建議使用類似下面的腳本:

#!/usr/bin/awk -f 
BEGIN { 
    FS = "," 
} 
/^DELTA Energy Terms/ { 
    capture = 1; 
    next 
} 
/Energy Terms$/ { 
    capture = 0; 
    next 
} 
/^Frame/ { next } 
(capture) { print $9 } 

保存腳本爲extract-delta,並使其可執行文件,那麼你可以使用它就像任何其他的shell命令:

$ cat input-file | tr -d '\015' | ./extract-delta 
-31.67263392 
-34.9402544 
-30.4327956 
-34.13569544 
+0

這一個幾乎完美的作品!如果我們做了「awk -F」/^DELTA/{capture = 1}/Energy Terms $/{next}/^ Frame/{next}(capture){print $ 9}'input> check.dat「尾隨(^ M)在每行的末尾。我可以知道背後的原因嗎? – Chubaka 2015-03-19 00:38:02

+0

這通常是由DOS樣式的行尾字符('\ r \ n')引起的。 '\ r'轉換爲Ctrl + M,'\ n'轉換爲Ctrl + J。您可以通過'tr -d'\ 015''過濾輸入以刪除回車符。 – 2015-03-19 02:17:29

+0

謝謝!我可以知道是否有任何awk手冊用於「捕獲」?搜索後我找不到任何東西。它看起來非常強大,並且很想挖掘更多。 – Chubaka 2015-03-19 02:36:56

0

您可以嘗試下面的awk命令。

$ awk -v RS="\n\n" -v FS="\n" '/^DELTA Energy Terms/{for(i=3;i<=NF;i++){split($i, a, /,/);print a[9]}}' RS= file 
-31.67263392 
-34.9402544 
-30.4327956 
-34.13569544 
  • RS="\n\n",所以一個空行被設置爲記錄分隔符。
  • FS="\n",換行符設置爲字段分隔符。
  • /^DELTA Energy Terms/如果一條記錄以^DELTA Energy Terms開頭,則對該特定記錄執行以下操作。
  • {for(i=3;i<=NF;i++){split($i, a, /,/);print a[9]}}迭代除1和2之外的所有字段,然後根據逗號拆分每個字段,然後將分散的項目存儲到名爲a的數組中。
  • print a[9]在關聯數組a的第9個索引處打印該元素。
0

您還可以使用bash做到這一點,使用下列內容:

tail -n +$((2 + $(grep -n "DELTA Energy Terms" input.txt | cut -d":" -f1))) input.txt | cut -d"," -f9 

tail -n +$((2 + $(grep -n "DELTA Energy Terms" input.txt部分將打印輸入文件的行,其中包含DELTA Energy條款加2,然後cut將爲您提供您要查找的第9個字段。