awk: How to search for a block within a block ?

Ok, I have some experience with awk, but I haven't touched it for years ... back again and I have one problem.

I have large char file, it has hundreds of major text blocks. First, I need to grab and process those, and ignore everything else. That bit is simple.

Within those major text blocks, there are 3 to 32 minor text blocks. Second, I need to process those. Here's what the data looks like this:

major_start
major data

minor_start
minor data 1
minor_end

minor_start
minor data 2
minor_end

...
minor_start
minor data 99
minor_end

major_end

This is what I would like to code (of course it doesn't work). Note, I need bits from the major_block while processing the minor_block, such as var1:

/major_start/,/major_end/ {

    if ( $1 == "fat" ) { var1=$7 }

    /minor_start/,/minor_end/ {

        / 0:/ { array1[0]=var1; array2[0]=$3; var3=$3 }
        if ( $1 == "thin" ) { var2=$9 }

        }

    }

I was certain I have done this before (without leaving awk), but I cannot find evidence of that. I looked at my old awk scripts, they seem to process the major_block; then use if-then-else. But the need was not quite the same.

I searched this forum, and the closest question is "parsing-file-extracting-useful-data-block". (close but not quite, because that particular bit did not get answered). I an seeking the following:

  1. Instructions to get awk to do what I want.

  2. Alternately, can I capture everything in major_block and write that to a file_B; then process it with "system(awk ... file_B)"

  3. Alternately, can someone who is an awk geek confirm to me that awk is a single-pass design, with no iteration.

TIA

Hi, DerekAsirvadem.

Welcome to the forum.

Thanks for posting your code snippet.

Note that Parsing file and extracting the useful data block contains a sample of the input and the expected output.

There have been many reads of your post, but no replies, suggesting that such samples will probably help attract pertinent and useful replies ... cheers, drl

PS If you decide to post code and data, please use CODE tags, just as you did for the snippet. A simple method: select text with your mouse, then click the icon just above the editing window.. The correct one looks like a hand on a keyboard, resulting in something like the block below:

code or data displayed in a CODE block for easy reading

DRL

Thanks. Done.

Hi,

You cannot use a range pattern inside another range pattern, but you could do something like this:

/major_start/                             { major_block=1 }
major_block                               { execute code that is inside the major block }
major_block && /minor_start/,/minor_end/  { execute code that is inside a minor block inside the major block }
/major_end/                               { major_block=0 }' 
1 Like

Scrutinzer

Sorry for the delayed response.

I didn't get an answer in time (had to rebuild a server over the holidays; needed the scripts working), so I implemented 32 IF statements. Works fine, but u.g.l.y.

Your solution is elegant. My need is a bit more complicated (I posted a simple example) but that's a minor problem on my side. I will use it, and re-implement my ugly code before the next execution. I have a similar need coming up in a few weeks, I can use it again.

Very RPG, incidentally, for the older scripters among us.

Thanks.

Scrutinizer

Changed my code; it works well. The code is substantially more readable, and the program is shorter.

Thanks again.