2011-03-29 83 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