mainframejcldfsort

Need to compare the same field in different records with JCL SORT


I have an input file, the 3rd field in this file is a number. This number usually is repeated in the same field for about 30-40 records, when a record is read that has a different value in this field I need the number '1' to print in the first position of the following record. e.g.

           7226184019519       317786762  0000000000001POP160
           7226184019522       317786762  0000000000001POP160
1          7226139045234       326446460  0000000000001POP160
           7226139045242       326446460  0000000000001POP160
           7226139045274       326446460  0000000000001POP160
           7226139045277       326446460  0000000000001POP160
           7226139045280       326446460  0000000000001POP160

I've tried using 'SECTIONS' like:

SORT FIELDS=COPY
   OUTFIL FNAMES=SORTOUT,
   SECTIONS=(26,9,HEADER3= (1:'1'))  

But this will print the number '1' on a separate line:

           7226184019519       317786762  0000000000001POP160
           7226184019522       317786762  0000000000001POP160
1          
           7226139045234       326446460  0000000000001POP160
           7226139045242       326446460  0000000000001POP160
           7226139045274       326446460  0000000000001POP160
           7226139045277       326446460  0000000000001POP160
           7226139045280       326446460  0000000000001POP160

I need something like overlay but I'm not sure how to use this with 'SECTIONS'.
Note: The number above, 317786762 starts in position 26.


AMENDMENT

I've figured out how to move the 1 to the first position(Code below). The requirement to complete this SORT is for a '1' to be printed in position 1 after every 30 records OR when the number in POS 26,9 changes.

//SYSIN     DD *
   SORT FIELDS=COPY
    INREC IFTHEN=(WHEN=INIT,OVERLAY=(101:SEQNUM,8,ZD,
       RESTART=(26,9))),
       IFTHEN=(WHEN=(101,8,ZD,EQ,30),
       OVERLAY=(1:C'1'))
/*

This code sets a sequence number in POS 101,8. It then restarts the Seqnum when there's a new value in 26,9. I also need the Sequence number to restart when the value of the SEQNUM is 30. But as far as I know Restart only works if the value of the field changes. You can't use logical expressions with it.

So my question is, Does anyone know a way to write a SORT that will read a sequential file and print a '1' in position 1 after every 30 records or after a new value is found in a certain field.


Solution

  • I'm guessing your records are fixed-length.

    Use INREC with IFTHEN=(WHEN=INIT... to temporarily extend the records to include a sequence number. The sequence number needs to be large enough to cover the maximum number of records that could be in a group (and make it a power of 10 larger). Use RESTART= on your sequence number, and specify your key field there.

    Then, as in another of your recent questions, use IFTHEN=(WHEN=(logicalexpression to identify the first of a group (sequence is one) and OVERLAY C'1' at column one.

    Use IFOUTLEN= with your original record-length, to return the records to their original size. IFOUTLEN says "after the completion of IFTHEN processing, set the record-length to this". Saves you having to do a BUILD to drop off the temporary extension.

    Procedure is slightly different (extend at the first data-position, 5, and must have a BUILD to return to size) for variable-length records.