Skip to main content

How to reverse a file content using JCL SORT?

Hello, Mainframers!!

Have you ever been asked to write a logic for reversing the file content, or any requirement to read the file in reverse order? In this post, I will try to explain how we can achieve the same using the SORT utility.

Let's assume we have a dataset as mentioned below.

  • Name: MFUSER.SORT.INPUT
  • RECFM=FB, LRECL=40
  • Type: PS

Input Dataset: It contains the list of Month names along with Unique Month ID in ascending order.

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 VIEW       MFUSER.SORT.INPUT                               Columns 00001 00040 
 Command ===>                                                  Scroll ===> CSR  
 =COLS> ----+----1----+----2----+----3----+----4                                
 ****** ***************************** Top of Data ******************************
 000001 01 JANUARY                                                              
 000002 02 FEBRUARY                                                             
 000003 03 MARCH                                                                
 000004 04 APRIL                                                                
 000005 05 MAY                                                                  
 000006 06 JUNE                                                                 
 000007 07 JULY                                                                 
 000008 08 AUGUST                                                               
 000009 09 SEPTEMBER                                                            
 000010 10 OCTOBER                                                              
 000011 11 NOVEMBER                                                             
 000012 12 DECEMBER                                                             
 ****** **************************** Bottom of Data ****************************

Sort JCL: As we have the Month ID in ascending order in the input dataset, we can use it as key for sorting the data in descending order and get the output we need.

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 EDIT       MFUSER.JCL(REVFILE) - 01.06                     Columns 00001 00072 
 Command ===>                                                  Scroll ===> CSR  
 =COLS> ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
 ****** ***************************** Top of Data ******************************
 000001 //REVFILE  JOB 1,NOTIFY=&SYSUID                                         
 000002 //STEP01   EXEC PGM=SORT                                                
 000003 //SYSPRINT DD   SYSOUT=*                                                
 000004 //SYSOUT   DD   SYSOUT=*                                                
 000005 //SORTIN   DD   DSN=&SYSUID..SORT.INPUT,DISP=SHR                        
 000006 //SORTOUT  DD   DSN=&SYSUID..SORT.OUTPUT,                               
 000007 //             DISP=(NEW,CATLG,DELETE),                                 
 000008 //             DCB=*.SORTIN,                                            
 000009 //             SPACE=(TRK,(1,2),RLSE)                                   
 000010 //SYSIN    DD *                                                         
 000011   SORT FIELDS=(1,2,ZD,D)                                                
 000012 /*                                                                      
 ****** **************************** Bottom of Data ****************************

Output Dataset: After the job execution, the output dataset has the data in the exact reverse order of what we have in the input dataset.

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 VIEW       MFUSER.SORT.OUTPUT                              Columns 00001 00040 
 Command ===>                                                  Scroll ===> CSR  
 =COLS> ----+----1----+----2----+----3----+----4                                
 ****** ***************************** Top of Data ******************************
 000001 12 DECEMBER                                                             
 000002 11 NOVEMBER                                                             
 000003 10 OCTOBER                                                              
 000004 09 SEPTEMBER                                                            
 000005 08 AUGUST                                                               
 000006 07 JULY                                                                 
 000007 06 JUNE                                                                 
 000008 05 MAY                                                                  
 000009 04 APRIL                                                                
 000010 03 MARCH                                                                
 000011 02 FEBRUARY                                                             
 000012 01 JANUARY                                                              
 ****** **************************** Bottom of Data ****************************

We have achieved the task as we have a unique key in the ascending/descending order, but what if we do not have any sorted key? What if we have just a list of data and need to reverse it without changing the order.

Input Dataset: Lets assume that our input dataset has only Month names and we have been asked to reverse the data. If we follow the same logic as we did earlier, it will not work as expected as we do not have any sorted key. Also, it sorts the data in alphabetic descending order.

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 EDIT       MFUSER.SORT.INPUT                                    Data set saved 
 Command ===>                                                  Scroll ===> CSR  
 =COLS> ----+----1----+----2----+----3----+----4                                
 ****** ***************************** Top of Data ******************************
 000001 JANUARY                                                                 
 000002 FEBRUARY                                                                
 000003 MARCH                                                                   
 000004 APRIL                                                                   
 000005 MAY                                                                     
 000006 JUNE                                                                    
 000007 JULY                                                                    
 000008 AUGUST                                                                  
 000009 SEPTEMBER                                                               
 000010 OCTOBER                                                                 
 000011 NOVEMBER                                                                
 000012 DECEMBER                                                                
 ****** **************************** Bottom of Data ****************************
 

Sort JCL:

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 EDIT       MFUSER.JCL(REVFILE) - 01.06                     Columns 00001 00072 
 Command ===>                                                  Scroll ===> CSR  
 =COLS> ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
 ****** ***************************** Top of Data ******************************
 000001 //REVFILE  JOB 1,NOTIFY=&SYSUID                                         
 000002 //STEP01   EXEC PGM=SORT                                                
 000003 //SYSPRINT DD   SYSOUT=*                                                
 000004 //SYSOUT   DD   SYSOUT=*                                                
 000005 //SORTIN   DD   DSN=&SYSUID..SORT.INPUT,DISP=SHR                        
 000006 //SORTOUT  DD   DSN=&SYSUID..SORT.OUTPUT,                               
 000007 //             DISP=(NEW,CATLG,DELETE),                                 
 000008 //             DCB=*.SORTIN,                                            
 000009 //             SPACE=(TRK,(1,2),RLSE)                                   
 000010 //SYSIN    DD *                                                         
 000011   SORT FIELDS=(1,40,CH,D)                                               
 000012 /*                                                                      
 ****** **************************** Bottom of Data ****************************
 

Output Dataset: Have you noticed the output dataset mentioned below? It didn't reverse the file content, but sorted the input data in descending order of alphabets. That's not what we have been asked. Our output dataset should contain the reverse order of what's there in the input dataset.

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 VIEW       MFUSER.SORT.OUTPUT                              Columns 00001 00040 
 Command ===>                                                  Scroll ===> CSR  
 =COLS> ----+----1----+----2----+----3----+----4                                
 ****** ***************************** Top of Data ******************************
 000001 SEPTEMBER                                                               
 000002 OCTOBER                                                                 
 000003 NOVEMBER                                                                
 000004 MAY                                                                     
 000005 MARCH                                                                   
 000006 JUNE                                                                    
 000007 JULY                                                                    
 000008 JANUARY                                                                 
 000009 FEBRUARY                                                                
 000010 DECEMBER                                                                
 000011 AUGUST                                                                  
 000012 APRIL                                                                   
 ****** **************************** Bottom of Data ****************************
 
Here is the updated version of SORT JCL in which we will use INREC & OUTREC to achieve the output what we are looking for.
  1. INREC FIELDS=(1,40,SEQNUM,10,ZD)
    • INREC statement allows us to reformat the input data before the input data is sorted, merged, or copied.
    • With this statement, we are reformatting the input data to have 10 digit sequence number at the end of each record i.e. from 41st position to 50th.
  2. SORT FIELDS=(41,10,ZD,D)
    • We are sorting the reformatted records based on the sequence number added with the INREC
  3. OUTREC FIELDS=(1,40)
    • OUTREC statement allows us to reformat the input data after the input data is sorted, merged, or copied.
    • We are now reformatting the records to exclude the sequence numbers we added and the data will be in the exact reverse order of the input data.

Sort JCL:

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 EDIT       MFUSER.JCL(REVFILE) - 01.06                     Columns 00001 00072 
 Command ===>                                                  Scroll ===> CSR  
 =COLS> ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
 ****** ***************************** Top of Data ******************************
 000001 //REVFILE  JOB 1,NOTIFY=&SYSUID                                         
 000002 //STEP01   EXEC PGM=SORT                                                
 000003 //SYSPRINT DD   SYSOUT=*                                                
 000004 //SYSOUT   DD   SYSOUT=*                                                
 000005 //SORTIN   DD   DSN=&SYSUID..SORT.INPUT,DISP=SHR                        
 000006 //SORTOUT  DD   DSN=&SYSUID..SORT.OUTPUT,                               
 000007 //             DISP=(NEW,CATLG,DELETE),                                 
 000008 //             DCB=*.SORTIN,                                            
 000009 //             SPACE=(TRK,(1,2),RLSE)                                   
 000010 //SYSIN    DD *                                                         
 000011   INREC FIELDS=(1,40,SEQNUM,10,ZD)                                      
 000012   SORT FIELDS=(41,10,ZD,D)                                              
 000013   OUTREC FIELDS=(1,40)                                                  
 000014 /*                                                                      
 ****** **************************** Bottom of Data ****************************
 

Output Dataset:

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 VIEW       MFUSER.SORT.OUTPUT                              Columns 00001 00040 
 Command ===>                                                  Scroll ===> CSR  
 =COLS> ----+----1----+----2----+----3----+----4                                
 ****** ***************************** Top of Data ******************************
 000001 DECEMBER                                                                
 000002 NOVEMBER                                                                
 000003 OCTOBER                                                                 
 000004 SEPTEMBER                                                               
 000005 AUGUST                                                                  
 000006 JULY                                                                    
 000007 JUNE                                                                    
 000008 MAY                                                                     
 000009 APRIL                                                                   
 000010 MARCH                                                                   
 000011 FEBRUARY                                                                
 000012 JANUARY                                                                 
 ****** **************************** Bottom of Data ****************************
 

Comments

Popular posts from this blog

How to Reverse a string with or without using REVERSE function?

Hello Readers! Have you ever wanted to REVERSE a string a Mainframe COBOL program, or have you ever been asked to reverse a string without using REVERSE function? If the answer is Yes, then you may find this post useful to you. In the below mentioned COBOL program, I used two different ways of reversing a string in COBOL program. Using FUNCTION REVERSE REVERSE function returns a character string of exactly same length as input, but in the reverse order. Using PERFORM VARYING UNTIL In this logic, we loop through each character of input string from end of input (i.e. Length) to beginning of input (i.e. Position=1) and store the characters in result variable using reference modification. Output: From the output, we can say that we are able to reverse the input, but have you noticed something? Reverse string output has leading spaces. It is because string variable is declared with 20 length, but the actual length length of string (i.e. z/OS Mainframer ) is 15. As input WS-STRING is Alpha...