Checking a file

I have a file as shown below:

%( PHASES
P
%)

%( SOURCES
(10,0.0)
(13,0.0)
(16,0.0)
(19,0.0)
(22,0.0)
(25,0.0)
(28,0.0)
(31,0.0)
(34,0.0)
(37,0.0)
(40,0.0)
(43,0.0)
(46,0.0)
(49,0.0)
(52,0.0)
(55,0.0)
(58,0.0)
(61,0.0)
(64,0.0)
(67,0.0)
(70,0.0)
(73,0.0)
(76,0.0)
(79,0.0)
(82,0.0)
(85,0.0)
(88,0.0)
(91,0.0)
(94,0.0)
(97,0.0)
(100,0.0)
(103,0.0)
(106,0.0)
(109,0.0)
(112,0.0)
(115,0.0)
(118,0.0)
(121,0.0)
(124,0.0)
(127,0.0)
(130,0.0)
(133,0.0)
(136,0.0)
(139,0.0)
(142,0.0)
(145,0.0)
(148,0.0)
(151,0.0)
(154,0.0)
(157,0.0)
(160,0.0)
(163,0.0)
(166,0.0)
(169,0.0)
(172,0.0)
(175,0.0)
(178,0.0)
(181,0.0)
(184,0.0)
(187,0.0)
(190,0.0)
(193,0.0)
(196,0.0)
(199,0.0)
%)

%< SOURCE 1
%( PHASE 1
10 0 0
13 5.92346 5.92346
16 10.3106 10.3106
19 13.9672 13.9672
22 16.9838 16.9838
25 19.4407 19.4407
28 21.4705 21.4705
31 23.1547 23.1547
34 24.6813 24.6813
37 26.0695 26.0695
40 27.3611 27.3611
43 28.631 28.631
46 29.8366 29.8366
49 30.9858 30.9858
%)
%>

%< SOURCE 2
%( PHASE 1
10 5.92346 5.92346
13 0 0
16 5.92346 5.92346
19 10.3106 10.3106
22 13.9672 13.9672
25 16.9838 16.9838
28 19.4407 19.4407
31 21.4705 21.4705
34 23.1547 23.1547
37 24.6813 24.6813
40 26.0695 26.0695
43 27.3611 27.3611
46 28.631 28.631
49 29.8366 29.8366
52 30.9858 30.9858
%)
%>

%< SOURCE 3
%( PHASE 1
10 10.3106 10.3106
13 5.92346 5.92346
16 0 0
19 5.92346 5.92346
22 10.3106 10.3106
25 13.9672 13.9672
28 16.9838 16.9838
31 19.4407 19.4407
34 21.4705 21.4705
37 23.1547 23.1547
40 24.6814 24.6814
43 26.0695 26.0695
46 27.3611 27.3611
49 28.631 28.631
52 29.8366 29.8366
55 30.9858 30.9858
%)
%>

I want to look at each section enclosed within

%< SOURCE 1
%( PHASE 1


%)
%>

Inside it I have a number of rows consisting of 3 numbers

Need to get $1 when $2 and $3 are zero within the block. i.e. get X, for the entry X 0 0 . Then I need to check if the difference between every first number in the block and X is less than 40. If it's greater I will report an error.

So within each block we do

abs(Xi-X) > 40 print "Error"

Following code tries to do simple state processing but the '%(' and '%)' are used in two contexts so it has to skip possible errors for those lines. It is possible to improve the state processing if needed.

awk -f test4.awk input4.txt

You could also pass in the 'delta' value on the command line. To do so, remove the delta assignment in the BEGIN block and use '-d delta=40' on the command line.

# File: test4.awk
BEGIN {
      state = 0;
      delta = 40;
}

/^[0-9]/ {
      if (state == 2) {
        if ($2 == 0 && $3 == 0) {
          printf("Info: Zeros found for %d, at line %d.\n", $1, FNR);
        }
        if (prev != -9999) {
          if (($1 - prev) > delta) {
            printf("Error: Sequence delta of %d exceeded, at line %d.\n", delta, FNR);
          }
        }
        prev = $1
      }
}

/%</ {
      if (state != 0) {
        printf("Error: wrong state %d, line %d.\n", state, FNR);
        exit;
      }
      state = 1;
      sourcen = $2;
      sourcev = $3;
}

/%\(/ {
      if (state == 1) {
        state = 2;
        phasen = $2;
        phasev = $3;
        prev = -9999;
        printf("Info: Processing %s %d: %s %d.\n", sourcen, sourcev,
           phasen, phasev);
      }
}

/%\)/ {
      if (state == 2) {
        state = 1;
      }
}

/%>/ {
      if (state != 1) {
        printf("Error: wrong state %d, line %d.\n", state, FNR);
        exit;
      }
      state = 0;
}

awk 'function abs(val) {return val>0?val:-val }
     BEGIN {RS="%<";FS="\n"}
     /SOURCE [0-9]/ {for (i=3;i<=NF;i++) 
                       {if (length($i)>2) 
                         {split($i,a," ") ;
                          {if (a[2]==0&&a[3]==0)
                                for (j=3;j<=NF;j++)
                                   {split($j,b," ") ;
                                     {if (abs(a[1]-b[1])>40) print $1,$i, $j," Error "}
                                   }
                          }
                         }  
                       }
                    }' urfile

The problem with m1xram code is that prev contains the $1 of the previous line. I need to do the check by subtracting each $1 from the $1 that contains two zeros within each block.

---------- Post updated at 11:24 AM ---------- Previous update was at 11:11 AM ----------

rdcwayx code seems ok.