1

I have some really poorly formatted data files, and unfortunately the format of the files produced cannot be altered. I was using GAWK to parse the data into a manageable format but now I've been given a new set of files that use a slightly different layout.

Using the example below, I needed to find out if there is a way to pull all of the rows for the first 2 columns of data shown below " cell". I understand I can keep copying and pasting getline; print $1,$2 but the number of rows can vary between 2 and 10000. Is there a way to build a loop that will read through all of the rows, stopping when it finds text or "=" instead of a number?

Ex. Data Set:

 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

Current Attempt:

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

Ex. Output Format:

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
    Would you show the output that is expected – user218374 Apr 18 '17 at 21:02
  • Would greatly benefit from having an example of desired output. – steve Apr 18 '17 at 21:22
  • @RakeshSharma Sorry, I've updated the question to show a desired output. – Jess Apr 18 '17 at 21:36
1
# print lines from /energy/ to /total/, not inclusive
awk '/total/{p=0};p;/energy/{p=1}' /path/to/input

This will just set have awk set p to 1 when /energy/ is seen, and set p to 0 when /total/ is seen. The bare p (the condition that triggers the printing of lines) will then be 1 on lines which you wish to print.

This can be refined to print exactly the data you want:

$ 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

To also print the second field when you see /1tally/, just add a specific trigger:

$ 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

To put a blank line between each outblock block, use /total/{p=0; print ""}

  • is there a way to modify the /energy/{p=1} entry so that it will seek out ' energy' (6 spaces) instead of just 'energy'? This word unfortunately occurs in a dozen different locations but the spaces before it help to determine the relevant lines. If not could I still use the 'cell' string I was using before? – Jess Apr 18 '17 at 22:19
  • Certainly: / energy/ hard-codes the six spaces into the search. Though the formatting here compressed the five spaces into one. slash, six spaces, 'energy', slash. If that's the start of the line, this should work too: /^ energy/ (again, pretend there are six spaces there). – DopeGhoti Apr 18 '17 at 22:26
  • Perfect! That fixes my problem exactly. The additional command for the blank line keeps giving me an error message when I try to add it though. It is purely aesthetic for my use, but is there something I missed? I tried to use it by changing /total/{p=0} to /total/{p=0; print ''} but this appears to be incorrect. – Jess Apr 18 '17 at 22:44
  • Oh, of course; we're overloading the quotes. Use /total/ { p=0; print "" }. – DopeGhoti Apr 18 '17 at 22:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.