I have a requirement to format the case of Names in a particular position in an FB file and write to output file.
The total length of the file being 507 bytes, FB File
The layout would be as follows:
1. Customer Number X(10)
2. Customer ID X(18)
3. Email ID X(100)
4. Title X(30)
5. Customer Name X(200)
6. Customer Address X(149)
The sample of the input file would be quite similar to this:
Code:
X123456775|1234567890123456|xyz@gmail.com |MR |JOHN WESLEY SAM |14,MAINSTREET LONDON|
My requirement is to write an output file with the Customer names to have a upper case on the first letter of each word and remaining as lower case. If there single apostophe then the first character after apostophe needs to upper and the character before it needs to be upper too.
The expected Output could be as below:
Code:
X123456775|1234567890123456|xyz@gmail.com |MR |John Wesley Sam |14,MAINSTREET LONDON|
There will be no space before the names and the character between the names would be either space,- or ', no other character is expected.
The limitation being that this should be done using DFSORT, i have been trying PARSE,BUILD and OVERLAY from the forum, however i am not able to reach at the solution
Multiple sort steps are fine, Any suggestions/build for this would be helpful.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Since the name field is 200 bytes long, so with a theoretical maximum of 100 name elements, plus the need to deal with the apostrophe and the hyphen and then to put everything back together and give it a squeeze, enrico's idea (and noting Craq's extension) is not a bad way to do it. Should be able to all fit in one FINDREP.
IFTHEN=(WHEN=INIT with OVERLAY to change to lower-case position 160 for a length of 199 (leaving the first as upper-case or blank) and then another IFTHEN=(WHEN=INIT with a big FINDREP from 159 for a length of 200.
You may or may not want to consider the names MacMillan and McMillan.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Nicely worked Mistah Kurtz. For DFSORT the L becomes a test with SS.
For a 200-byte field, there will be 200 tests per record, and probably well over 150 LTOUs. The work can probably be reduced by using AND and testing that the next byte is non-blank. This will only do the number of LTOUs necessary. Being a "one ahead" process, you need to stop one byte before the end.
SORT has no looping structures. So this code is a loop, but "flattened out".
FINDREP does its own looping, but we have to hand-code the conversion.
shajeeth,
Put the AND in and test both. Let us know if one is more rapid than the other.
Nicely worked Mistah Kurtz. For DFSORT the L becomes a test with SS.
For a 200-byte field, there will be 200 tests per record, and probably well over 150 LTOUs. The work can probably be reduced by using AND and testing that the next byte is non-blank. This will only do the number of LTOUs necessary. Being a "one ahead" process, you need to stop one byte before the end.
SORT has no looping structures. So this code is a loop, but "flattened out".
FINDREP does its own looping, but we have to hand-code the conversion.
shajeeth,
Put the AND in and test both. Let us know if one is more rapid than the other.
Thanks for the valuable suggestions!! I thought i would split the 200 bytes into 20 bytes each assuming each part of name will not be more than twenty bytes(used one of the older post from Frank Yaeger). Used PARSE and BUILD to create the output...
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Is this a once-off exercise?
If so, you can work out the maxima - elements, length of elements and characters in total.
1) Change everything except first character of maximum-needed length to lower-case.
FINDREP, 26 for each, for blank-letter, hyphen-letter, apostrophe-letter.
2) Change everything except first character, then look byte-by-byte (hard-coded) to identify blank, hyphen and and apostrophe then change next character to upper-case. (watch the last character).
3) The PARSE approach. Need to know the number of elements (maximum) and need three sets of PARSE/SQZ, each of which will be executed (nothing to say you can't have "Rupert O'Neill-Smith".
You can make a slight saving on the PARSE code you have shown. Once you know the fixed positions (at the moment the place where the first character is returned to upper-case) instead only covert the start+1,length-1 bytes to lower-case (no other case-conversion), leaving the first untouched.
I think the PARSE route would be the most complex for your requirement.
If so, you can work out the maxima - elements, length of elements and characters in total.
1) Change everything except first character of maximum-needed length to lower-case.
FINDREP, 26 for each, for blank-letter, hyphen-letter, apostrophe-letter.
2) Change everything except first character, then look byte-by-byte (hard-coded) to identify blank, hyphen and and apostrophe then change next character to upper-case. (watch the last character).
3) The PARSE approach. Need to know the number of elements (maximum) and need three sets of PARSE/SQZ, each of which will be executed (nothing to say you can't have "Rupert O'Neill-Smith".
You can make a slight saving on the PARSE code you have shown. Once you know the fixed positions (at the moment the place where the first character is returned to upper-case) instead only covert the start+1,length-1 bytes to lower-case (no other case-conversion), leaving the first untouched.
I think the PARSE route would be the most complex for your requirement.
This is not going to be a one off exercise, this JCL is to be run daily!
Looks like Parsing is not giving me desired results, finally i have decided to try the byte by byte conversion as suggested by all here..
Since there is a potential chance of more special characters to be included, i have started to build based below
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Please use the Code tags when posting anything which needs spacing preserved.
Look at mistah kurtz's second example with FINDREP. That's three values to change lowercase a to uppercase A for your three scenarios. You just need another 25 triples, and you're set (change the positions, operate on the entire 200 bytes after UTOL for the last 199 bytes).
I think this is going to be your best shot. You don't need to code in hex literals, you can use character (C' a',C' A',C'-a',C'-A',C'''a',C'''A'....) if you prefer.
You can use SORT, Rexx, ISPF editor to knock together the FINDREP you need easily.
Another way to do the IFTHEN if you insist on that is with a big bunch of CHANGEs.
Code 20 IFTHENs. Code the FINDREP. Run on expected daily amount of data. If the IFTHENs look good, double them and repeat. If the IFTHENs give you better performance for the whole 200, then you have a possibility.
Joined: 28 Jan 2012 Posts: 316 Location: Room: TREE(3). Hilbert's Hotel
Here is an example of the first approach outlined by Bill, using FINDREP.
Code:
//STEP01 EXEC PGM=SORT
//SORTIN DD *
JOHN WESLEY SAM
DEL-RAFAEL
O'KEEFE
SAMSON
SURESH MENON
RUPERT O'NEILL-SMITH
//SORTOUT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSIN DD *
OPTION COPY
INREC IFTHEN=(WHEN=INIT,
OVERLAY=(2:2,30,TRAN=UTOL))
OUTREC FINDREP=(INOUT=(C' a',C' A',C'-a',C'-A',C'''a',C'''A',
C' b',C' B',C'-b',C'-B',C'''b',C'''B',
C' c',C' C',C'-c',C'-C',C'''c',C'''C',
C' d',C' D',C'-d',C'-D',C'''d',C'''D',
C' e',C' E',C'-e',C'-E',C'''e',C'''E',
C' f',C' F',C'-f',C'-F',C'''f',C'''F',
C' g',C' G',C'-g',C'-G',C'''g',C'''G',
C' h',C' H',C'-h',C'-H',C'''h',C'''H',
C' i',C' I',C'-i',C'-I',C'''i',C'''I',
C' j',C' J',C'-j',C'-J',C'''j',C'''J',
C' k',C' K',C'-k',C'-K',C'''k',C'''K',
C' l',C' L',C'-l',C'-L',C'''l',C'''L',
C' m',C' M',C'-m',C'-M',C'''m',C'''M',
C' n',C' N',C'-n',C'-N',C'''n',C'''N',
C' o',C' O',C'-o',C'-O',C'''o',C'''O',
C' p',C' P',C'-p',C'-P',C'''p',C'''P',
C' q',C' Q',C'-q',C'-Q',C'''q',C'''Q',
C' r',C' R',C'-r',C'-R',C'''r',C'''R',
C' s',C' S',C'-s',C'-S',C'''s',C'''S',
C' t',C' T',C'-t',C'-T',C'''t',C'''T',
C' u',C' U',C'-u',C'-U',C'''u',C'''U',
C' v',C' V',C'-v',C'-V',C'''v',C'''V',
C' w',C' W',C'-w',C'-W',C'''w',C'''W',
C' x',C' X',C'-x',C'-X',C'''x',C'''X',
C' y',C' Y',C'-y',C'-Y',C'''y',C'''Y',
C' z',C' Z',C'-z',C'-Z',C'''z',C'''Z'))
Output:
Code:
John Wesley Sam
Del-Rafael
O'Keefe
Samson
Suresh Menon
Rupert O'Neill-Smith