从多个位置的 2 列中提取多行数据

从多个位置的 2 列中提取多行数据

我有一些格式非常糟糕的数据文件,不幸的是生成的文件的格式无法更改。我曾使用 GAWK 将数据解析为可管理的格式,但现在我得到了一组新的文件,它们的布局略有不同。

使用下面的示例,我需要找出是否有一种方法可以提取“单元格”下方显示的前两列数据的所有行。我知道我可以继续复制和粘贴getline; print $1,$2,但行数可能在 2 到 10000 之间变化。有没有办法构建一个循环来读取所有行,在找到文本或“=”而不是数字时停止?

前任。数据集:

 1tally        8        nps =  2000000000       
       particle(s): neutrons 
       this tally is modified

 cell  20001                                                                                                                           
      energy   
    0.0000E+00   0.00000E+00 0.0000
    1.0000E-05   1.10650E-06 0.0213
    1.0000E-03   1.15086E-04 0.0021
    1.0000E-01   8.12322E-03 0.0002
    1.9231E-01   3.65758E-03 0.0004
    2.5000E+00   0.00000E+00 0.0000
      total      1.60091E-02 0.0002

 ===================================================================================================================================

           results of 10 statistical checks

1tally       38        nps =  2000000000
      particle(s): neutrons 
      this tally is modified

 cell  20001                                                                                                                           
      energy   
    0.0000E+00   0.00000E+00 0.0000
    1.0000E-05   1.10650E-06 0.0213
    1.0000E-03   1.15086E-04 0.0021
    1.0000E-01   8.12322E-03 0.0002
    1.2400E-01   1.20892E-03 0.0006
    1.4800E-01   1.00911E-03 0.0007
    1.7200E-01   8.39342E-04 0.0008
    1.9600E-01   6.99704E-04 0.0008
      total      1.60091E-02 0.0002

 ===================================================================================================================================

           results of 10 statistical checks

目前的尝试:

/^1tally.*[0-9]/ {print $2};
/^ cell/ {getline; getline; print $1,$2}

前任。输出格式:

8
0.0000E+00   0.00000E+00
1.0000E-05   1.10650E-06
1.0000E-03   1.15086E-04
1.0000E-01   8.12322E-03
1.9231E-01   3.65758E-03
2.5000E+00   0.00000E+00

38
0.0000E+00   0.00000E+00
1.0000E-05   1.10650E-06
1.0000E-03   1.15086E-04
1.0000E-01   8.12322E-03
1.2400E-01   1.20892E-03
1.4800E-01   1.00911E-03
1.7200E-01   8.39342E-04
1.9600E-01   6.99704E-04

答案1

# print lines from /energy/ to /total/, not inclusive
awk '/total/{p=0};p;/energy/{p=1}' /path/to/input

这只会在看到时awk设置p为 1 ,并在看到时设置为 0 。然后,裸线(触发行打印的条件)将位于您要打印的行上。/energy/p/total/p1

可以对其进行改进以准确打印您想要的数据:

$ awk '/total/{p=0} p==1 {print $1,$2} /energy/{p=1}' input
0.0000E+00 0.00000E+00
1.0000E-05 1.10650E-06
1.0000E-03 1.15086E-04
1.0000E-01 8.12322E-03
1.9231E-01 3.65758E-03
2.5000E+00 0.00000E+00

要在看到 时也打印第二个字段/1tally/,只需添加特定触发器:

$ awk '/1tally/ {print $2}  /total/{p=0} p==1 {print $1,$2} /energy/{p=1}' input
8
0.0000E+00 0.00000E+00
1.0000E-05 1.10650E-06
1.0000E-03 1.15086E-04
1.0000E-01 8.12322E-03
1.9231E-01 3.65758E-03
2.5000E+00 0.00000E+00

要在每个 outblock 块之间放置一个空行,请使用/total/{p=0; print ""}

相关内容