*KEYWORD
$TIME_VALUE = 1.4000002e+001
$STATE_NO = 15
$Output for State 15 at time = 14
*ELEMENT_SHELL_THICKNESS
1346995 25 1457683 1471891 1457727 1471929
9.953265e-001 9.953265e-001 9.953265e-001 9.953265e-001
1346996 25 1471891 1457685 1471930 1457727
9.953963e-001 9.953963e-001 9.953963e-001 9.953963e-001
1346997 25 1457685 1471892 1471931 1471930
9.953437e-001 9.953437e-001 9.953437e-001 9.953437e-001
*End
所以期望的输出可能是
min=9.953265e-001 on line 07 at 1346995
max=9.953963e-001 on line 09 at 1346996
如果我们知道行号,一个可能的解决方案是
cat your_file | awk '
NR >= 6 && NR <= 11{at=$1;getline
if (max < $1){max=$1;max_line=NR;max_at=at}
if (min > $1){min=$1;min_line=NR;min_at=at}}
NR == 7{min=$1;min_line=NR;min_at=at}
END{
printf "min=%-13e on line %02d at %8d\n", min, min_line, min_at
printf "max=%-13e on line %02d at %8d\n", max, max_line, max_at}'
但是如果我想在
*Keyword
和 *End
之间搜索怎么办,因为由于文件中的微小变化,字符串到达定义的行并且其值为 0,因此最小值设置为零。
我必须提到这个好的解决方案是由jfgagne在我之前的问题中提供的:输入文件的某些行中带有行号标记的min和max。
向脚本添加状态。如果您的状态变量为 false,则在查看开始标记时将其设置为 true;无论如何,跳到下一行。 如果你的状态变量为真;如果查看结束标记,则将状态变量设置为 false,并跳到下一行;否则,您就在该地区;像以前一样处理线路。
awk '!there{if($1 == "*ELEMENT_SHELL_THICKNESS") there=1; next}
there&&/^\*End$/{there=0;next}
{at=$1;getline
if (!max || max < $1){max=$1;max_line=NR;max_at=at}
if (!min || min > $1){min=$1;min_line=NR;min_at=at}}
END{
printf "min=%-13e on line %02d at %8d\n", min, min_line, min_at
printf "max=%-13e on line %02d at %8d\n", max, max_line, max_at}' your_file
我假设开始标记是代码建议的
*ELEMENT_SHELL_THICKNESS
,而不是您在问题中所说的*KEYWORD
。 我删除了 min
和 max
初始化代码,主要是出于懒惰;如果其中一个可以为零,也许你应该把它放回去。
这也消除了cat