2011-03-29 79 views
1

考慮通過管道連接到awk的流。線條由交錯的字段名和字段值序列,如下面的例子(行真的是更長的時間並列出許多其他屬性):在435如何通過名稱從「名稱值名稱值...」中提取值 - 類似輸入行

樣品2978閔-0.068689在1389阿明1.0406e-08最大0.0514581 1375個
樣品2977閔-0.100258在1293阿明-1.06743e-08在3最大0.0989735在1282個
樣品2977閔-0.109783在1281阿明-2.97293e-08在10最大0.139651在1268個
樣品2976分-0.116509 at 1269 Amin -1.04306e-09 at 161最大0.0985577 at 1255

我想從字符串中提取某個值作爲參考,例如,Min。如果我在awk中有類似scanf的功能,我首先使用ind=index($0, "Min"),然後s=substr($0, ind),然後sscanf(s,"Min %f", &val)獲得val。但是,我沒有任何可用的awk中的scanf

如何通過名稱提取值呢?

回答

2

你經歷的每個字段,檢查 「最小」,然後提取下一個字段

$ awk '{for(o=1;o<=NF;o++) if ($o =="Min") {print $(o+1)} }' file 
-0.068689 
-0.100258 
-0.109783 
-0.116509 

紅寶石(1.9+)

$ ruby -ne 'puts $_.scan(/Min\s+(.[^\s]*)/)' file 
1

\ 1。你不能依賴數據元素在每個記錄中的相同列位置嗎?那麼你可以簡單地說

awk '{print $3}' dataFile 

要獲得您的示例中的最小值。

\ 2。 Kurumi的想法很好。

\ 3。下面是確保你匹配的數據爲標籤

awk '{ 
    minVal=$0 
    sub(/^.*Min /, "",minVal) 
    sub(/ .*$/, "", minVal) 
    printf minVal" " 
    maxVal=$0 
    sub(/^.*Max /, "",maxVal) 
    sub(/ .*$/, "", maxVal) 
    printf maxVal "\n" 
    } ' dataFile 

您可以直接做$ 0修改的另一種方法,但由於AWK「重新計算」的字段值每次$ 0編輯,這將是(以我的經驗)一過程要慢得多。

我希望這會有所幫助。

+0

運行由於值緊跟名字,它可能會更容易找到''從字符串name',削減的第一次相遇$ 0'並分配回'$ 0'。這樣,所需的價值總是在$ 2。 – mbaitoff 2011-03-29 05:22:40

0

這將按字段只掃描包含標籤的行。

BEGIN {a="^Min$"} 

/a/ {for(i = 1; i <= $NF; i++) { if (match($i,a)) print $i,$(i+1)}}  

- >

Min -0.068689 
Min -0.100258 
Min -0.109783 
Min -0.116509 

ideone