IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

find 4 character string from same record.


IBM Mainframe Forums -> JCL & VSAM
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
ramsri

Active User


Joined: 18 Oct 2008
Posts: 380
Location: India

PostPosted: Tue Oct 09, 2012 8:27 am
Reply with quote

Hi, I have a FB file with LRECL=80 as shown below. My requirement is to find a particular 4 character string that appears multiple times within one record. For example, this 4 character string "2501" appears 3 times in 1st, 3 times in 2nd and 4 times in 3rd record and so on. How to get this count?

Code:

ABC123110225012501250120793187
BCA2342132809325012501207931692501
CBA13250122132501280932501207925013169
NSA4125012213250128093250120793169250169872501
FUL3041456324625026789



Please help. Thanks.
Back to top
View user's profile Send private message
gcicchet

Senior Member


Joined: 28 Jul 2006
Posts: 1702
Location: Australia

PostPosted: Tue Oct 09, 2012 2:09 pm
Reply with quote

Hi,

you can try this, the result is in pos 81-82
Code:
//STEP0001 EXEC PGM=SORT                                                       
//SYSOUT   DD SYSOUT=*                                                         
//SORTIN   DD *                                                                 
ABC123110225012501250120793187                                                 
BCA2342132809325012501207931692501                                             
CBA13250122132501280932501207925013169                                         
NSA4125012213250128093250120793169250169872501                                 
FUL3041456324625026789                                                         
25012501250125012501250125012501250125012501250125012501250125012501250125012501
//SORTOUT  DD SYSOUT=*                                                         
//SYSIN DD *                                                                   
  OPTION COPY                                                                   
  INREC IFTHEN=(WHEN=INIT,OVERLAY=(081:20X)),                                   
  IFTHEN=(WHEN=INIT,                                                           
       PARSE=(%01=(STARTAT=C'2501',FIXLEN=1),                                   
              %02=(STARTAT=C'2501',FIXLEN=1),                                   
              %03=(STARTAT=C'2501',FIXLEN=1),                                   
              %04=(STARTAT=C'2501',FIXLEN=1),                                   
             %05=(STARTAT=C'2501',FIXLEN=1),                       
             %06=(STARTAT=C'2501',FIXLEN=1),                       
             %07=(STARTAT=C'2501',FIXLEN=1),                       
             %08=(STARTAT=C'2501',FIXLEN=1),                       
             %09=(STARTAT=C'2501',FIXLEN=1),                       
             %10=(STARTAT=C'2501',FIXLEN=1),                       
             %11=(STARTAT=C'2501',FIXLEN=1),                       
             %12=(STARTAT=C'2501',FIXLEN=1),                       
             %13=(STARTAT=C'2501',FIXLEN=1),                       
             %14=(STARTAT=C'2501',FIXLEN=1),                       
             %15=(STARTAT=C'2501',FIXLEN=1),                       
             %16=(STARTAT=C'2501',FIXLEN=1),                       
             %17=(STARTAT=C'2501',FIXLEN=1),                       
             %18=(STARTAT=C'2501',FIXLEN=1),                       
             %19=(STARTAT=C'2501',FIXLEN=1),                       
             %20=(STARTAT=C'2501',FIXLEN=1)),                       
 OVERLAY=(081:%01,%02,%03,%04,%05,%06,%07,%08,%09,%10,             
              %11,%12,%13,%14,%15,%16,%17,%18,%19,%20)),           
 IFTHEN=(WHEN=INIT,FINDREP=(STARTPOS=081,INOUT=(C'2',C'1'))),       
  IFTHEN=(WHEN=INIT,                                                           
 OVERLAY=(101:(081,1,UFF,ADD,082,1,UFF,ADD,083,1,UFF,ADD,084,1,UFF,ADD,       
               085,1,UFF,ADD,086,1,UFF,ADD,087,1,UFF,ADD,088,1,UFF,ADD,       
               089,1,UFF,ADD,090,1,UFF,ADD,091,1,UFF,ADD,092,1,UFF,ADD,       
               093,1,UFF,ADD,094,1,UFF,ADD,095,1,UFF,ADD,096,1,UFF,ADD,       
               097,1,UFF,ADD,098,1,UFF,ADD,099,1,UFF,ADD,100,1,UFF),           
               EDIT=(TT)))                                                     
                                                                               
  OUTREC BUILD=(1,80,101,2)                                                   
//*                                                                           



A similar solution to this was posted by Kolusu but couldn't find the link to it, so all the credit goes to Kolusu.
Gerry
Back to top
View user's profile Send private message
ramsri

Active User


Joined: 18 Oct 2008
Posts: 380
Location: India

PostPosted: Tue Oct 09, 2012 4:41 pm
Reply with quote

Gerry, thanks but I have 309783 records in input file and was showing few sample records only icon_rolleyes.gif
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Tue Oct 09, 2012 4:50 pm
Reply with quote

Ramsri,

What is your output to look like?
Back to top
View user's profile Send private message
ramsri

Active User


Joined: 18 Oct 2008
Posts: 380
Location: India

PostPosted: Tue Oct 09, 2012 5:43 pm
Reply with quote

Bill,

Expected Output:
Code:

ABC123 2501 2501 2501
BCA234 250125012501
CBA132 2501 2501 2501 2501
NSA412 2501 2501 2501 2501 2501


If the above is not possible, at least count of 2501 is ok.

Code:

ABC123 3
BCA234 3
CBA132 4
NSA412 5


Thanks.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Tue Oct 09, 2012 6:09 pm
Reply with quote

I have to say count is much easier to produce, and much easier to understand afterwards. If you just list, then a human has to still do the counting... they all have the same value...

Have a search for HUMPHREY in the DFSORT forum. That is for characters, but the same will apply for "strings" with a bit of extra calculation.
Back to top
View user's profile Send private message
gcicchet

Senior Member


Joined: 28 Jul 2006
Posts: 1702
Location: Australia

PostPosted: Wed Oct 10, 2012 3:43 am
Reply with quote

Hi,

Quote:
Gerry, thanks but I have 309783 records in input file and was showing few sample records only
I'm not sure why the number of records is an issue.

For this result
Code:
ABC123 3
BCA234 3
CBA132 4
NSA412 5
just replace
Code:
  OUTREC BUILD=(1,80,101,2)     
to
Code:
  OUTREC BUILD=(1,6,X,101,2) 




For this result
Code:
ABC123 2501 2501 2501
BCA234 250125012501
CBA132 2501 2501 2501 2501
NSA412 2501 2501 2501 2501 2501
use the following
Code:
  OPTION COPY                                           
  INREC IFTHEN=(WHEN=INIT,OVERLAY=(081:80X)),           
  IFTHEN=(WHEN=INIT,                                     
       PARSE=(%01=(STARTAT=C'2501',FIXLEN=4),           
              %02=(STARTAT=C'2501',FIXLEN=4),           
              %03=(STARTAT=C'2501',FIXLEN=4),           
              %04=(STARTAT=C'2501',FIXLEN=4),           
              %05=(STARTAT=C'2501',FIXLEN=4),           
              %06=(STARTAT=C'2501',FIXLEN=4),           
              %07=(STARTAT=C'2501',FIXLEN=4),           
              %08=(STARTAT=C'2501',FIXLEN=4),           
              %09=(STARTAT=C'2501',FIXLEN=4),           
              %10=(STARTAT=C'2501',FIXLEN=4),           
              %11=(STARTAT=C'2501',FIXLEN=4),           
              %12=(STARTAT=C'2501',FIXLEN=4),           
              %13=(STARTAT=C'2501',FIXLEN=4),           
              %14=(STARTAT=C'2501',FIXLEN=4),           
              %15=(STARTAT=C'2501',FIXLEN=4),           
              %16=(STARTAT=C'2501',FIXLEN=4),           
              %17=(STARTAT=C'2501',FIXLEN=4),           
              %18=(STARTAT=C'2501',FIXLEN=4),                     
              %19=(STARTAT=C'2501',FIXLEN=4),                     
              %20=(STARTAT=C'2501',FIXLEN=4)),                     
  OVERLAY=(081:%01,%02,%03,%04,%05,%06,%07,%08,%09,%10,           
               %11,%12,%13,%14,%15,%16,%17,%18,%19,%20))           
                                                                   
  OUTREC BUILD=(1,6,X,081,4,                                       
                    X,085,4,                                       
                    X,089,4,                                       
                    X,093,4,                                       
                    X,097,4,                                       
                    X,101,4,                                       
                    X,105,4,                                       
                    X,109,4,                                       
                    X,113,4,                                       
                    X,117,4,                                       
                    X,121,4,                                       
                    X,125,4,                                       
                    X,129,4,                                       
                    X,133,4,                                       
                    X,137,4,                                       
                    X,141,4,                       
                    X,145,4,                       
                    X,149,4,                       
                    X,153,4,                       
                    X,157,4)                       
//*                                                 



Gerry
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Wed Oct 10, 2012 4:50 am
Reply with quote

A different approach. Works on a VB, so you'd need a step to make VB from your FB.

If you don't like the symbols/SYMNAMES just run the job with no input and paste the code from the sysout for the step, reformatting as is your wont.

Code:
//TOV   EXEC PGM=SORT
//SORTIN DD *
ABC123110225012501250120793187
BCA2342132809325012501207931692501
CBA13250122132501280932501207925013169
NSA4125012213250128093250120793169250169872501
FUL3041456324625026789
//SYSOUT   DD SYSOUT=*
//SORTOUT DD DSN=&&OUT,DISP=(,PASS),UNIT=SYSDA,SPACE=(CYL,1)
//SYSIN DD *
  OPTION COPY
  OUTFIL FTOV
//HUMPHREY EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYMNAMES DD *
RECORD-RDW,1,4,CH
RDW-RECORD-LENGTH,=,2,BI
RDW-RESERVED,*,2,CH
RECORD-START-OF-DATA,*,1,CH
RECORD-START-OF-DATA-COL,=
BUILD-ORIGINAL-RECORD-LENGTH,=,2,BI
RECORD-WITH-ADDED-RL-START-OF-DATA,*,1,CH
RECORD-WITH-ADDED-RL-START-OF-DATA-COL,=
POSITION,RECORD-WITH-ADDED-RL-START-OF-DATA
RECORD-KEY,*,6,CH
POSITION,RECORD-START-OF-DATA
OUTPUT-KEY,*,6,CH
OUTPUT-COUNT,*,2,CH
LENGTH-ADJUST-FOR-NEW-RECORD-LENGTH,+2
SEARCH-CHAR-OR-STRING,C'2501'
ARBITRARY-HEX-STRING,X'FFFFFE'
NO-STRING-FOUND,C'00'
//SYMNOUT DD SYSOUT=*
//SYSIN DD *
                                                             
 OPTION COPY
                                                           
 INREC  IFTHEN=(WHEN=INIT,
                BUILD=(RECORD-RDW,
                       RDW-RECORD-LENGTH,
                       RECORD-START-OF-DATA-COL)),
                                                           
       IFTHEN=(WHEN=INIT,
                FINDREP=(IN=SEARCH-CHAR-OR-STRING,
                         OUT=ARBITRARY-HEX-STRING,
                         STARTPOS=13)),
                                                           
       IFTHEN=(WHEN=INIT,
                BUILD=(RECORD-RDW,
                       RECORD-KEY,
                       BUILD-ORIGINAL-RECORD-LENGTH,
                      SUB,
                       RDW-RECORD-LENGTH,
                      ADD,
                       LENGTH-ADJUST-FOR-NEW-RECORD-LENGTH,
                      TO=ZDF,
                      LENGTH=2))
 OUTFIL OMIT=(OUTPUT-COUNT,EQ,NO-STRING-FOUND),
        VTOF,
        BUILD=(OUTPUT-KEY,X,OUTPUT-COUNT,80:X)
//SORTIN  DD DSN=&&OUT,DISP=(OLD,PASS)


Output is:
Code:

ABC123 03
BCA234 03
CBA132 03
NSA412 04


Note that my results are different from yours. For CBA and NSA the "2" at the start of the first 2501 you count is from the "key" so it would seem "unusual" to count it just because it happens to appear when data starts "501".
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Wed Oct 10, 2012 5:30 am
Reply with quote

Another, for fixed-length records. You can have a maximum of 18 "2501"s (excluding the key from your 80 bytes) so append 18 Xs to the end of each record. Then do the FINDREP, reducing the size of the storage occupied by the new string by one. This "shifts" the 18 added Xs one to the left for each "hit", padding with space. After the FINDREP, discover how many Xs are left of the 18.

One advantage of this over the PARSE is no limit of 100 that can be counted (doesn't matter in this example).

Note that this and the other as they stand are both "destructive" of their input records.

Both solutions developed with DFSORT.

Code:
//HUMPHREY EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYMNAMES DD *
INPUT-RECORD,*,80,CH
RECORD-EXTENSION,*,18,CH
OUTPUT-SEPARATOR,7,1,CH
OUTPUT-COUNT,8,2,CH
OUTPUT-LAST-BYTE,80,1,CH
SEARCH-CHAR-OR-STRING,C'2501'
ARBITRARY-HEX-STRING,X'FFFFFE'
NO-STRING-FOUND,C'00'
C18XS,'XXXXXXXXXXXXXXXXXX'
C00-CHANGES,'XXXXXXXXXXXXXXXXXX'
C01-CHANGE,'XXXXXXXXXXXXXXXXX '
C02-CHANGES,'XXXXXXXXXXXXXXXX  '
C03-CHANGES,'XXXXXXXXXXXXXXX   '
C04-CHANGES,'XXXXXXXXXXXXXX    '
C05-CHANGES,'XXXXXXXXXXXXX     '
C06-CHANGES,'XXXXXXXXXXXX      '
C07-CHANGES,'XXXXXXXXXXX       '
C08-CHANGES,'XXXXXXXXXX        '
C09-CHANGES,'XXXXXXXXX         '
C10-CHANGES,'XXXXXXXX          '
C11-CHANGES,'XXXXXXX           '
C12-CHANGES,'XXXXXX            '
C13-CHANGES,'XXXXX             '
C14-CHANGES,'XXXX              '
C15-CHANGES,'XXX               '
C16-CHANGES,'XX                '
C17-CHANGES,'X                 '
C18-CHANGES,'                  '
C00-COUNT,C'00'
C01-COUNT,C'01'
C02-COUNT,C'02'
C03-COUNT,C'03'
C04-COUNT,C'04'
C05-COUNT,C'05'
C06-COUNT,C'06'
C07-COUNT,C'07'
C08-COUNT,C'08'
C09-COUNT,C'09'
C10-COUNT,C'10'
C11-COUNT,C'11'
C12-COUNT,C'12'
C13-COUNT,C'13'
C14-COUNT,C'14'
C15-COUNT,C'15'
C16-COUNT,C'16'
C17-COUNT,C'17'
C18-COUNT,C'18'
//SYMNOUT DD SYSOUT=*
//SYSIN DD *
                                                     
 OPTION COPY
                                                     
 INREC  IFOUTLEN=9,
        IFTHEN=(WHEN=INIT,
                OVERLAY=(RECORD-EXTENSION:C18XS)),
                                                     
       IFTHEN=(WHEN=INIT,
                FINDREP=(IN=SEARCH-CHAR-OR-STRING,
                         OUT=ARBITRARY-HEX-STRING,
                         STARTPOS=7)),
                                                     
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C00-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C00-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C01-CHANGE),
                 OVERLAY=(OUTPUT-COUNT:C01-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C02-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C02-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C03-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C03-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C04-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C04-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C05-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C05-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C06-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C06-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C07-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C07-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C08-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C08-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C09-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C09-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C10-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C10-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C11-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C11-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C12-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C12-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C13-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C13-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C14-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C14-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C15-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C15-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C16-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C16-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C17-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C17-COUNT)),
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,C18-CHANGES),
                 OVERLAY=(OUTPUT-COUNT:C18-COUNT))
                                                     
 OUTFIL OMIT=(OUTPUT-COUNT,EQ,NO-STRING-FOUND),
        OVERLAY=(OUTPUT-SEPARATOR:X,
                 OUTPUT-LAST-BYTE:X)
//SORTIN  DD *
ABC123110225012501250120793187
BCA2342132809325012501207931692501
CBA13250122132501280932501207925013169
NSA4125012213250128093250120793169250169872501
FUL3041456324625026789


Output is:

Code:
ABC123 03
BCA234 03
CBA132 03
NSA412 04
Back to top
View user's profile Send private message
ramsri

Active User


Joined: 18 Oct 2008
Posts: 380
Location: India

PostPosted: Wed Oct 10, 2012 8:04 am
Reply with quote

Gerry/Bill,

Thanks for your help. I will try it out today icon_biggrin.gif

I tried this code upon Gerry's 1st idea and got results (1st output) icon_smile.gif

Code:

//SYSIN    DD *                                                 
  INREC PARSE=(%01=(STARTAT=C'2501',FIXLEN=4),                 
               %02=(STARTAT=C'2501',FIXLEN=4),                 
               %03=(STARTAT=C'2501',FIXLEN=4),                 
               %04=(STARTAT=C'2501',FIXLEN=4),                 
               %05=(STARTAT=C'2501',FIXLEN=4),                 
               %06=(ENDAT=BLANKS,FIXLEN=4)),                   
               BUILD=(1,6,X,%01,X,%02,X,%03,X,%04,X,%05,X,%06) 
  SORT FIELDS=COPY                                             


Have a wonderful day !
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Wed Oct 10, 2012 12:20 pm
Reply with quote

If you really just want them listed, then what you have shown is all you need. I would put ABSPOS=7 on the first PARSE so it doesn't look in the "key". Bear in mind you need as many as the logical/actual maximum occurences.
Back to top
View user's profile Send private message
ramsri

Active User


Joined: 18 Oct 2008
Posts: 380
Location: India

PostPosted: Wed Oct 10, 2012 2:13 pm
Reply with quote

Bill, Thanks. What does ABSPOS=7 do? Can you please give me an example of ADDPOS also, if possible?
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10872
Location: italy

PostPosted: Wed Oct 10, 2012 2:19 pm
Reply with quote

Quote:
What does ABSPOS=7 do?

why don' t You start looking at the <Your SORT product > manuals Yourself ? icon_evil.gif
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Wed Oct 10, 2012 4:08 pm
Reply with quote

As enrico indicates, there is an easy way for you to answer your first.

ADDPOS and SUBPOS you use when you want to adjust the starting-point of the next PARSE by a known value. The "known value" doesn't have to give you an exact "hit", just so that the PARSE can find the correct starting-point when that is before the end of the previous PARSE (including what has defined the end of the PARSE) or where bytes are known to be not needed.

You might want to include what has delimited the previous PARSE as data in the next PARSE for instance, so use SUBPOS. Basically, anything you need that starts before the end point of the previous PARSE.

You might want to "skip" the prefix of a field, so ADDPOS. Basically, anything you need that starts further than the end point of the previous PARSE.
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Wed Oct 10, 2012 8:36 pm
Reply with quote

Hello,

Quote:
Can you please give me an example of ADDPOS also, if possible?
You have now been here nearly 4 years.

Is there some reason you continue to refuse to learn to work with the materials you have at hand (manuals, forum topics, etc).

We are here to help, but do not intend to be a manual reading service.
Back to top
View user's profile Send private message
ramsri

Active User


Joined: 18 Oct 2008
Posts: 380
Location: India

PostPosted: Thu Oct 11, 2012 11:27 am
Reply with quote

Quote:

Is there some reason you continue to refuse to learn to work with the materials you have at hand (manuals, forum topics, etc).


If I don't learn how I would ask a question icon_lol.gif
One needs a basic knowledge to work on it and not the extreme stuff which is used once in a while.. icon_cool.gif

Thanks.
Back to top
View user's profile Send private message
ramsri

Active User


Joined: 18 Oct 2008
Posts: 380
Location: India

PostPosted: Thu Oct 11, 2012 12:09 pm
Reply with quote

Hi Bill the Superman,

I have ran both FB and VB solutions given by you and got the expected results icon_biggrin.gif

Thank you very much & have a great weekend.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Fri Oct 12, 2012 5:33 am
Reply with quote

I was thinking the thing a little "clunky" for Fixed compared to Variable. So...

Code:
//HUMPHREY EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYMNAMES DD *
INPUT-RECORD,*,80,CH
RECORD-EXTENSION,26,18,CH
RECORD-EXTENSION-1ST-BYTE,=,1,ZD
SKIP,7
RECORD-EXTENSION-8TH-BYTE,*,=,CH
OUTPUT-SEPARATOR,7,1,CH
OUTPUT-COUNT,8,2,ZD
OUTPUT-LAST-BYTE,80,1,CH
SEARCH-CHAR-OR-STRING,C'A'
ARBITRARY-STRING,C''
NO-STRING-FOUND,+0
DIGITS-18,'012345678901234567'
MAX-COUNT,+18
ALL-SPACE,C' '
ONE-SPACE,C' '
//SYMNOUT DD SYSOUT=*
//SYSIN DD *
                                                     
 OPTION COPY
                                                     
 INREC IFOUTLEN=9,
       IFTHEN=(WHEN=INIT,
                OVERLAY=(RECORD-EXTENSION:DIGITS-18)),
                                                     
       IFTHEN=(WHEN=INIT,
                FINDREP=(IN=SEARCH-CHAR-OR-STRING,
                         OUT=ARBITRARY-STRING,
                         STARTPOS=7,
                         ENDPOS=25)),
                                                     
       IFTHEN=(WHEN=INIT,
                 OVERLAY=(OUTPUT-COUNT:
                           RECORD-EXTENSION-1ST-BYTE,
                           TO=ZD,LENGTH=2)),
                                                             
       IFTHEN=(WHEN=(RECORD-EXTENSION,EQ,ALL-SPACE),
                 OVERLAY=(OUTPUT-COUNT:MAX-COUNT,
                           TO=ZD,LENGTH=2)),
                                                             
       IFTHEN=(WHEN=(RECORD-EXTENSION-8TH-BYTE,EQ,ONE-SPACE),
                 OVERLAY=(OUTPUT-COUNT:OUTPUT-COUNT,
                           ADD,+10,
                           TO=ZD,LENGTH=2))
                                                             
 OUTFIL OMIT=(OUTPUT-COUNT,EQ,NO-STRING-FOUND),
        OVERLAY=(OUTPUT-SEPARATOR:X,
                 OUTPUT-LAST-BYTE:X)
//SORTIN  DD *
ABC000AAAAAAAAAAAAAAAAAA
ABC001AAAAAAAAAAAAAAAAA
ABC002AAAAAAAAAAAAAAAA
ABC003AAAAAAAAAAAAAAA
ABC004AAAAAAAAAAAAAA
ABC005AAAAAAAAAAAAA
ABC006AAAAAAAAAAAA
ABC007AAAAAAAAAAA
ABC008AAAAAAAAAA
ABC009AAAAAAAAA
ABC010AAAAAAAA
ABC011AAAAAAA
ABC012AAAAAA
ABC013AAAAA
ABC014AAAA
ABC015AAA
ABC016AA
ABC017A
ABC018



Gives:
Code:
ABC000 18
ABC001 17
ABC002 16
ABC003 15
ABC004 14
ABC005 13
ABC006 12
ABC007 11
ABC008 10
ABC009 09
ABC010 08
ABC011 07
ABC012 06
ABC013 05
ABC014 04
ABC015 03
ABC016 02
ABC017 01


It would then be a more "reasonable" amount of code to get to over 100 if necessary.

One proviso. This runs with DFSORT, I don't know if SyncSort is going to handle the third WHEN=INIT for the first record :-)
Back to top
View user's profile Send private message
ramsri

Active User


Joined: 18 Oct 2008
Posts: 380
Location: India

PostPosted: Mon Oct 15, 2012 7:37 pm
Reply with quote

Hi,

Ran it as it is and got the results.......thanks once again icon_biggrin.gif
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon Oct 15, 2012 8:04 pm
Reply with quote

Thanks for letting us know.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sun Apr 07, 2013 4:04 pm
Reply with quote

Got an update for this. A Bug Fix, as the original FINDREP has no ENDPOS (so could get false hits if counting numerics). And a simplification, to use a binary count value instead of the character one.

The binary method can count up to 255 simply, and beyond would not be onerous.

Code:
//HUMPHREY EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYMNAMES DD *
*
* The character or string to be counted
*
  SEARCH-CHAR-OR-STRING,C'1'
*
* Contents of ARBITRARY-STRING are irrelevant, as long as one byte
* shorter than SEARCH-CHAR-OR-STRING.
*
  ARBITRARY-STRING,C''
*
* In binary, from zero to the maximum to be counted. If line is filled,
* multiple constants will be needed.
*
  COUNTS-18,X'000102030405060708090A0B0C0D0E0F101112'
*
* Important - define the entire input record here.
*
  INPUT-RECORD,*,80,CH
* Define DUMMY... imemdiately after the record, it is "POSITION'ed" to
* later.
*
  DUMMY-FOR-FIRST-BYTE-AFTER-RECORD,*,1,CH
*
* Fields prefixed OUTPUT- are just for the example, not part
* of the solution.
*
  OUTPUT-SEPARATOR,25,1,CH
  OUTPUT-COUNT,26,2,ZD
  OUTPUT-LAST-BYTE,80,1,CH
*
* To locate to first byte after end of record.
*
  POSITION,DUMMY-FOR-FIRST-BYTE-AFTER-RECORD
*
* The following must be have the length of count constant(s), else some
* danger of a false hit.
*
  EXTENSION-FOR-COUNTS-UNDERFLOW,*,19,CH
*
* If the constant for the count required splitting (see above)
* then each part of the constant requires a unique starting position
* immediately after then end of the previous one.
*
  EXTENSION-FOR-COUNTS,*,=,CH
*
* This will hold the count, in binary of length one, starting from zero
* and going up to maximum needed, to a maximum of 255.
*
  EXTENSION-FOR-COUNTS-1ST-BYTE,=,1,BI
//SYMNOUT DD SYSOUT=*
//SYSIN DD *
                                                                       
 OPTION COPY
                                                                       
* IFOUTLEN is just for the example, not part of the solution.
*
 INREC IFOUTLEN=80,
                                                                       
* Establishes the count contant(s) in the extention to the input record.
*
       IFTHEN=(WHEN=INIT,
                OVERLAY=(EXTENSION-FOR-COUNTS:COUNTS-18)),
                                                                       
* Does the required search, in the example from position 7 to position
* 80, change these to what is needed.
*
       IFTHEN=(WHEN=INIT,
                FINDREP=(IN=SEARCH-CHAR-OR-STRING,
                         OUT=ARBITRARY-STRING,
                         STARTPOS=7,
                         ENDPOS=80)),
                                                                       
* The appended constant has been shifted left by the FINDREP for each
* instance of the character/string found, so that the first byte of the
* extended counts points to the count of times shifted.
* The leading part of the appended count constant has "underflowed"
* into the place established for it. The count of successful searches
* is just sitting there in a one-byte binary field.
*
       IFTHEN=(WHEN=INIT,
                 OVERLAY=(OUTPUT-COUNT:
                           EXTENSION-FOR-COUNTS-1ST-BYTE,
                           TO=ZD,
                          LENGTH=2)),
                                                                       
* Just formatting for the output example.
*
       IFTHEN=(WHEN=INIT,
                 OVERLAY=(OUTPUT-SEPARATOR:
                           X,
                          OUTPUT-LAST-BYTE:
                           X))
//SORTIN  DD *
ABC000111111111111111111
ABC00111111111111111111
ABC0021111111111111111
ABC003111111111111111
ABC00411111111111111
ABC0051111111111111
ABC006111111111111
ABC00711111111111
ABC0081111111111
ABC009111111111
ABC01011111111
ABC0111111111
ABC012111111
ABC01311111
ABC0141111
ABC015111
ABC01611
ABC0171
ABC018
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> JCL & VSAM

 


Similar Topics
Topic Forum Replies
No new posts How to split large record length file... DFSORT/ICETOOL 7
No new posts Replace each space in cobol string wi... COBOL Programming 2
No new posts PARSE Syntax for not fix length word ... JCL & VSAM 7
No new posts SFTP Issue - destination file record ... All Other Mainframe Topics 2
No new posts Sortjoin and Search for a String and ... DFSORT/ICETOOL 1
Search our Forums:

Back to Top