Awk 如何按名称从“中提取值”;名称值名称值…”-像输入行一样

Awk 如何按名称从“中提取值”;名称值名称值…”-像输入行一样,awk,Awk,考虑通过管道传输到awk的一系列行。行由一系列交错的字段名和字段值组成,如以下示例所示(列有许多其他属性的行实际上要长得多): 1389时样品2978 Min-0.068689,435时样品1.0406e-08,1375时样品最大0.0514581 样品2977最小值-1293时为0.100258,最大值为1.06743e-08,最大值为0.0989735,1282时为0.0989735 样品2977最小值-1281时为0.109783最小值-2.97293e-08最大值为10时为0.13965

考虑通过管道传输到
awk
的一系列行。行由一系列交错的字段名和字段值组成,如以下示例所示(列有许多其他属性的行实际上要长得多):

1389时样品2978 Min-0.068689,435时样品1.0406e-08,1375时样品最大0.0514581
样品2977最小值-1293时为0.100258,最大值为1.06743e-08,最大值为0.0989735,1282时为0.0989735
样品2977最小值-1281时为0.109783最小值-2.97293e-08最大值为10时为0.139651最大值为1268时为0.139651
样品2976最小值-0.116509在1269处,最小值-1.04306e-09在161处,最大值0.0985577在1255处

我想从字符串中提取一个特定的值,使用它的名称作为指导,例如,
Min
。如果我在
awk
中有一个类似
scanf
的函数,我会首先使用
ind=index($0,“Min”)
,然后使用
s=substr($0,ind)
,然后使用
sscanf(s,“Min%f”,&val)
来获得
val
。但是,我在awk中没有任何
scanf


那么,我如何通过名称提取值呢?

你检查每个字段,检查“Min”,然后提取下一个字段

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

\一,。您不能依赖数据元素在每个记录中处于相同的列位置吗?那么你可以简单地说

awk '{print $3}' dataFile
根据示例获取最小值

\二,。库鲁米的主意不错

\三,。下面是另一种方法,可以确保数据与其标签匹配

awk '{
     minVal=$0
     sub(/^.*Min /, "",minVal)
     sub(/ .*$/, "", minVal)
     printf minVal" "
     maxVal=$0
     sub(/^.*Max /, "",maxVal)
     sub(/ .*$/, "", maxVal)
     printf maxVal "\n"
   } '  dataFile
您可以直接对$0进行修改,但由于每次编辑$0时awk都会“重新计算”字段值,因此(以我的经验)这将是一个慢得多的过程


我希望这有帮助

这将逐个字段仅扫描包含标签的行

BEGIN {a="^Min$"}

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

运行时,由于值紧跟在名称之后,因此可能更容易找到
名称
的第一次相遇,从
$0
中剪切字符串,并重新分配给
$0
。这样,所需的值始终为
$2
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