MVSFORUMS.com A Community of and for MVS Professionals
View previous topic :: View next topic
Author
Message
pete Beginner Joined: 02 Dec 2002 Posts: 22 Topics: 9 Location: www.state.ct.us
Posted: Wed Sep 03, 2003 2:12 pm Post subject: can sort convert tab delimited fields to fixed locations
This can be accomplished with a program, but can sort do this ?
I have records that look like (a period was used to represent a tab : X'05'):
Code:
1000001.jack.smith.1/1/2001.the good, bad, and ugly company.pertsmith.nh
1000003.billy bob.ng.12/21/1999.vandolay industries.waco.tx
1000009.joe.blacksmith.10/1/2001.unemployed programmer.anytown.pa
the fields for the output file should line up like the following (field names and coulmns have been added for clarification)....
Code:
(account)(fname) (lname) (date) (company) (city) (st)
1 2 3 4 5 6 7 8 9
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
1000001 jack smith 1/1/2001 the good, bad, and ugly company pertsmith nh
1000003 billy bob ng 12/21/1999 vandolay industries waco tx
1000009 joe blacksmith 10/1/2001 unemployed programmer anytown pa
Thanks. _________________ Regards,
Pete. Last edited by pete on Thu Sep 04, 2003 6:23 am; edited 1 time in total
Back to top
kolusu Site Admin Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
Posted: Wed Sep 03, 2003 2:40 pm Post subject:
Pete,
The position of the '.' is varible which makes it hard for sort to achieve the desired results.But if you have file-aid in your shop then the following JCl will give you the desired results.
Code:
//STEP0100 EXEC PGM=FILEAID
//SYSLIST DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//DD01 DD *
1000001.JACK.SMITH.1/1/2001.THE GOOD, BAD, AND UGLY COMPANY.PERTSMITH.NH
1000003.BILLY BOB.NG.12/21/1999.VANDOLAY INDUSTRIES.WACO.TX
1000009.JOE.BLACKSMITH.10/1/2001.UNEMPLOYED PROGRAMMER.ANYTOWN.PA
//DD01O DD SYSOUT=*
//SYSIN DD *
$$DD01 COPY REPLALL=(01,00,X'4B',X'05'),OUT=0
/*
File-aid scans every record for '.' (hex value of '4B') and replaces it with tab character(x'05') irrespective of position.
Hope this helps...
cheers
kolusu
Back to top
pete Beginner Joined: 02 Dec 2002 Posts: 22 Topics: 9 Location: www.state.ct.us
Posted: Wed Sep 03, 2003 3:06 pm Post subject:
Yes sir, I do have Fileaid.
I was not clear about the period. I just used it for demonstration purposes to represent a TAB ( could not think of a way to type a hex '05' but x'4b' will do ).
Anyway, I was looking for a process that converts the input records to output records where account is in position 1, first name starts at postion 9, last name starts at position 22, date starts at postion 38, etc. for all the records.
Thanks for your response. _________________ Regards,
Pete.
Back to top
vijay Beginner Joined: 09 May 2003 Posts: 131 Topics: 64
Posted: Wed Sep 03, 2003 3:39 pm Post subject:
If u've SAS in ur shop use it for this.
Sample example to do this kind of formatting:
Code:
//SASTEP EXEC SAS8,REGION=5400K
//SYSPRINT DD SYSOUT=*
//FILEOUT DD DSN=***************,DISP=SHR
//FILEIN DD DSN=****************,DISP=SHR
//SYSIN DD *
DATA _NULL_;
LENGTH EDIOFF $ 05
FIELD1 $ 05
ADDR1 $ 30
ADDR2 $ 30
FIELD2 $ 30
CITY $ 30
PROVCD $ 30
POSTCD $ 30
PHONENUM $ 30
FAXNUM $ 30
FIRSTNAME $ 30
MIDNAME $ 30
LASTNAME $ 30
FIELD3 $ 30
DENTID $ 30
FIELD4 $ 30
FIELD5 $ 30
FIELD6 $ 30
CTYPE $ 30
FIELD7 $ 30
FIELD8 $ 30
FIELD9 $ 30;
INFILE FILEIN LRECL=500 DSD MISSOVER;
INPUT EDIOFF $
FIELD1 $
ADDR1 $
ADDR2 $
FIELD2 $
CITY $
PROVCD $
POSTCD $
PHONENUM $
FIRSTNAME $
MIDNAME $
LASTNAME $
FIELD3 $
DENTID $
FIELD4 $
FIELD5 $
FIELD6 $
CTYPE $
FIELD7 $
FIELD8 $
FIELD9 $ ;
FILE FILEOUT;
PUT @01 EDIOFF
@20 FIELD1
@40 ADDR1
@80 ADDR2
@120 FIELD2
@160 CITY
@200 PROVCD
@240 POSTCD
@280 PHONENUM
@320 FAXNUM
@360 FIRSTNAME
@400 MIDNAME
@440 LASTNAME
@480 FIELD3
@520 DENTID
@540 FIELD4
@580 FIELD5
@620 FIELD6
@660 CTYPE;
//*
FAXNUM $
FIRSTNAME $
MIDNAME $
LASTNAME $
FIELD3 $
DENTID $
FIELD4 $
FIELD5 $
FIELD6 $
CTYPE $
FIELD7 $
FIELD8 $
FIELD9 $ ;
FILE FILEOUT;
PUT @01 EDIOFF
@20 FIELD1
@40 ADDR1
@80 ADDR2
@120 FIELD2
@160 CITY
@200 PROVCD
@240 POSTCD
@280 PHONENUM
@320 FAXNUM
@360 FIRSTNAME
@400 MIDNAME
@440 LASTNAME
@480 FIELD3
@520 DENTID
@540 FIELD4
@580 FIELD5
@620 FIELD6
@660 CTYPE;
//*
Back to top
vijay Beginner Joined: 09 May 2003 Posts: 131 Topics: 64
Posted: Wed Sep 03, 2003 3:41 pm Post subject:
SAS will take care of delimiters etc., and is very easy.If u've SAS and need help ,let me know.
Back to top
vijay Beginner Joined: 09 May 2003 Posts: 131 Topics: 64
Posted: Wed Sep 03, 2003 3:43 pm Post subject:
or use EZT like this
Code:
//MAT1013C JOB (1243847,4SL07,PPPPPP,TEST),'JOB FOR MVS COMPILE',
// CLASS=L,MSGCLASS=X,NOTIFY=MAT1013
/*JOBPARM RESTART=N,LINES=99999
//JOBLIB DD DSN=EX94N.GROUP.Y2KPLOAD,DISP=SHR
// DD DSN=EX900.PRODLOAD,DISP=SHR
// DD DSN=EX900.EASYPLUS.LOADLIB,DISP=SHR
// DD DSN=SYS2.CAI.EZTP062.CAILIB.TORONTO,DISP=SHR
//*
//STEP01 EXEC PGM=EZTPA00,REGION=2500K
//ERRPRINT DD SYSOUT=*
//EZTVFM DD UNIT=WORK,SPACE=(4096,(100,100))
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//FILEA DD DSN=EX4XC.RMJ.PROVI2,DISP=SHR
//FILEB DD DSN=EX4XC.RMJ.PROVI2.FMT,DISP=SHR
*
*LIST OFF
FILE FILEA
REC-A 1 300 A
*
FILE FILEB
REC-B 1 190 A
*--------------------------------------------------------------------*
* WORKING STORAGE FOR THE OUTPUT RECORD *
*--------------------------------------------------------------------*
WS-OUTREC W 300 A
WS-EDI-OFF WS-OUTREC 05 A
WS-FILLER1 WS-OUTREC +05 02 A VALUE ' '
WS-SKIP1 WS-OUTREC +07 03 A
WS-FILLER2 WS-OUTREC +10 02 A VALUE ' '
WS-ADDR1 WS-OUTREC +12 30 A
WS-FILLER3 WS-OUTREC +42 02 A VALUE ' '
WS-ADDR2 WS-OUTREC +44 30 A
WS-FILLER4 WS-OUTREC +74 02 A VALUE ' '
WS-SKIP2 WS-OUTREC +76 03 A
WS-FILLER5 WS-OUTREC +79 02 A VALUE ' '
WS-CITY WS-OUTREC +81 20 A
WS-FILLER6 WS-OUTREC +101 02 A VALUE ' '
WS-PROV WS-OUTREC +103 02 A
WS-FILLER7 WS-OUTREC +105 02 A VALUE ' '
WS-POSTCD WS-OUTREC +107 06 A
WS-FILLER8 WS-OUTREC +113 02 A VALUE ' '
WS-PHNUM WS-OUTREC +115 10 A
WS-FILLER9 WS-OUTREC +125 02 A VALUE ' '
WS-FAXNUM WS-OUTREC +127 10 A
WS-FILLER10 WS-OUTREC +137 02 A VALUE ' '
WS-FIRNAME WS-OUTREC +139 11 A
WS-FILLER11 WS-OUTREC +150 02 A VALUE ' '
WS-MIDINIT WS-OUTREC +152 1 A
WS-FILLER12 WS-OUTREC +153 02 A VALUE ' '
WS-LASTNAM WS-OUTREC +155 18 A
WS-FILLER13 WS-OUTREC +173 02 A VALUE ' '
WS-SKIP3 WS-OUTREC +175 3 A
WS-FILLER14 WS-OUTREC +178 02 A VALUE ' '
WS-DENKEY WS-OUTREC +180 10 A
WS-FILLER15 WS-OUTREC +190 02 A VALUE ' '
WS-SKIP4 WS-OUTREC +192 3 A
WS-FILLER16 WS-OUTREC +195 02 A VALUE ' '
WS-SKIP5 WS-OUTREC +197 3 A
WS-FILLER17 WS-OUTREC +200 02 A VALUE ' '
WS-SKIP6 WS-OUTREC +202 3 A
WS-FILLER18 WS-OUTREC +205 02 A VALUE ' '
WS-CTYPE WS-OUTREC +207 3 A
WS-FILLER19 WS-OUTREC +210 02 A VALUE ' '
WS-SKIP7 WS-OUTREC +212 3 A
WS-FILLER20 WS-OUTREC +215 02 A VALUE ' '
WS-SKIP8 WS-OUTREC +217 3 A
WS-FILLER21 WS-OUTREC +220 02 A VALUE ' '
WS-SKIP9 WS-OUTREC +222 3 A
*--------------------------------------------------------------------*
* WORKING STORAGE VARIABLES*
*--------------------------------------------------------------------*
WS-REC W 300 A
WS-BYTE WS-REC 1 A OCCURS 300
WS-COUNT W 3 N
WS-COUNT1 W 3 N
WS-COUNT2 W 3 N
WS-VARMAX W 35 A
WS-VARMAX-B WS-VARMAX 1 A OCCURS 35
WK-POSTCD W 6 A
WK-POSTCD-B WK-POSTCD 1 A OCCURS 06
WK-PHNUM W 10 A
WK-PHNUM-B WK-PHNUM 1 A OCCURS 10
*
JOB INPUT FILEA
*
MOVE SPACES TO WS-OUTREC
PERFORM PROCESS-FILE
MOVE WS-OUTREC TO REC-B
PUT FILEB
*
PROCESS-FILE. PROC
*----------------------
WS-COUNT = 1
WS-REC = ''
WS-OUTREC = ''
MOVE REC-A TO WS-REC
IF WS-BYTE(WS-COUNT) = X'05'
WS-EDI-OFF = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-EDI-OFF
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-SKIP1 = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM SKIP-FIELD
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-ADDR1 = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-ADDR1
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-ADDR2 = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-ADDR2
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-SKIP2 = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM SKIP-FIELD
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-CITY = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-CITY
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-PROV = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-PROV
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-POSTCD = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
PERFORM CONV-POSTCD
MOVE WK-POSTCD TO WS-POSTCD
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-PHNUM = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
PERFORM CONV-PHNUM
MOVE WK-PHNUM TO WS-PHNUM
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-FAXNUM = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
PERFORM CONV-PHNUM
MOVE WK-PHNUM TO WS-FAXNUM
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-FIRNAME = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-FIRNAME
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-MIDINIT = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-MIDINIT
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-LASTNAM = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-LASTNAM
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-SKIP3 = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM SKIP-FIELD
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-DENKEY = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-DENKEY
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-SKIP4 = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM SKIP-FIELD
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-SKIP5 = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM SKIP-FIELD
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-SKIP6 = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM SKIP-FIELD
END-IF
IF WS-BYTE(WS-COUNT) = X'05'
WS-CTYPE = ''
WS-COUNT = WS-COUNT + 1
ELSE
PERFORM GET-FIELD
MOVE WS-VARMAX TO WS-CTYPE
END-IF
WS-SKIP7 = ''
WS-SKIP8 = ''
WS-SKIP9 = ''
END-PROC
*
GET-FIELD. PROC
*----------------------
WS-COUNT1 = 1
WS-VARMAX = ''
DO WHILE WS-BYTE(WS-COUNT) NE X'05'
MOVE WS-BYTE(WS-COUNT) TO WS-VARMAX-B(WS-COUNT1)
WS-COUNT = WS-COUNT + 1
WS-COUNT1 = WS-COUNT1 + 1
END-DO
WS-COUNT = WS-COUNT + 1
END-PROC
*
SKIP-FIELD. PROC
*--------------------
DO WHILE WS-BYTE(WS-COUNT) NE X'05'
WS-COUNT = WS-COUNT + 1
END-DO
WS-COUNT = WS-COUNT + 1
END-PROC
*
CONV-POSTCD. PROC
*--------------------
WS-COUNT1 = 1
WS-COUNT2 = 1
DO WHILE WS-COUNT1 < 11
IF WS-VARMAX-B(WS-COUNT1) NOT SPACES
MOVE WS-VARMAX-B(WS-COUNT1) TO WK-POSTCD-B(WS-COUNT2)
WS-COUNT1 = WS-COUNT1 + 1
WS-COUNT2 = WS-COUNT2 + 1
ELSE
WS-COUNT1 = WS-COUNT1 + 1
END-IF
END-DO
END-PROC
*
CONV-PHNUM. PROC
*--------------------
WS-COUNT1 = 1
WS-COUNT2 = 1
DO WHILE WS-COUNT1 < 20
IF WS-VARMAX-B(WS-COUNT1) NOT SPACES AND +
WS-VARMAX-B(WS-COUNT1) NE '(' AND +
WS-VARMAX-B(WS-COUNT1) NE ')' AND +
WS-VARMAX-B(WS-COUNT1) NE '-'
MOVE WS-VARMAX-B(WS-COUNT1) TO WK-PHNUM-B(WS-COUNT2)
WS-COUNT1 = WS-COUNT1 + 1
WS-COUNT2 = WS-COUNT2 + 1
ELSE
WS-COUNT1 = WS-COUNT1 + 1
END-IF
END-DO
END-PROC
Back to top
pete Beginner Joined: 02 Dec 2002 Posts: 22 Topics: 9 Location: www.state.ct.us
Posted: Wed Sep 03, 2003 4:57 pm Post subject:
Thanks vijay. I'll try the EZtrive program. _________________ Regards,
Pete.
Back to top
kolusu Site Admin Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
Posted: Thu Sep 04, 2003 8:35 am Post subject:
pete ,
A simpler version than the code posted above. I assumed that your input file is of 80 bytes length.I used reference modification(similar to cobol) and case(evaluate in cobol) in this program.Notice that I used '*' for the output field declarations which means that easytrieve will calculate the start position based on the lengths of the fields.
Code:
//STEP0100 EXEC PGM=EZTPA00
//STEPLIB DD DSN=CORP.EASYTREV.PROD.LOADLIB,
// DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSSNAP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//FILEIN DD *
1000001.JACK.SMITH.1/1/2001.THE GOOD, BAD, AND UGLY COMPANY.PERTSMITH.NH
1000003.BILLY BOB.NG.12/21/1999.VANDOLAY INDUSTRIES.WACO.TX
1000009.JOE.BLACKSMITH.10/1/2001.UNEMPLOYED PROGRAMMER.ANYTOWN.PA
//FILEOUT DD SYSOUT=*,
// DCB=(RECFM=FB,LRECL=98,BLKSIZE=0)
//SYSIN DD *
FILE FILEIN
IN-REC 01 80 A
W-STRING W 80 A
W-STR W-STRING 1 A OCCURS 80
W-SUB W 02 N 0
W-START-POS W 02 N 0 VALUE 1
W-STR-LENGTH W 02 N 0
W-DLM-COUNT W 02 N 0 VALUE 0
FILE FILEOUT FB(0 0)
ACCOUNT 01 08 A
FNAME * 10 A
LNAME * 20 A
ODATE * 10 A
COMPANY * 30 A
CITY * 10 A
STATE * 10 A
JOB INPUT(FILEIN)
W-STRING = IN-REC
W-SUB = 1
DO UNTIL W-SUB GT 80
CASE W-STR (W-SUB)
WHEN '.'
W-DLM-COUNT = W-DLM-COUNT + 1
W-STR-LENGTH = W-SUB - W-START-POS
PERFORM MOVE-TO-FIELD
W-START-POS = W-SUB + 1
W-SUB = W-SUB + 1
OTHERWISE
W-SUB = W-SUB + 1
END-CASE
END-DO
PUT FILEOUT
MOVE ZERO TO W-STR-LENGTH W-DLM-COUNT
W-START-POS = 1
MOVE-TO-FIELD. PROC
CASE W-DLM-COUNT
WHEN 1
MOVE W-STR (W-START-POS) W-STR-LENGTH TO ACCOUNT
WHEN 2
MOVE W-STR (W-START-POS) W-STR-LENGTH TO FNAME
WHEN 3
MOVE W-STR (W-START-POS) W-STR-LENGTH TO LNAME
WHEN 4
MOVE W-STR (W-START-POS) W-STR-LENGTH TO ODATE
WHEN 5
MOVE W-STR (W-START-POS) W-STR-LENGTH TO COMPANY
WHEN 6
MOVE W-STR (W-START-POS) W-STR-LENGTH TO CITY
W-START-POS = W-SUB + 1
W-STR-LENGTH = 80 - W-START-POS
MOVE W-STR (W-START-POS) W-STR-LENGTH TO STATE
END-CASE
END-PROC
Hope this helps...
cheers
kolusu
Back to top
Frank Yaeger Sort Forum Moderator Joined: 02 Dec 2002 Posts: 1618 Topics: 31 Location: San Jose
Posted: Tue May 23, 2006 3:18 pm Post subject:
With z/OS DFSORT V1R5 PTF UK90007 or DFSORT R14 PTF UK90006 (April, 2006), you can now use DFSORT's new PARSE and JFY functions to do this kind of thing quite easily as shown by the DFSORT job below:
Code:
//S1 EXEC PGM=ICEMAN
//SYSOUT DD SYSOUT=*
//SYMNAMES DD *
tab,X'05'
branch,1,7
first_name,%00
last_name,%1
date,%02
company,%03
city,%04
state,%05
//SORTIN DD DSN=... input file
//SORTOUT DD DSN=... output file
//SYSIN DD *
OPTION COPY
INREC PARSE=(first_name=(ABSPOS=9,FIXLEN=12,ENDBEFR=tab),
last_name=(FIXLEN=15,ENDBEFR=tab),
date=(FIXLEN=10,ENDBEFR=tab),
company=(FIXLEN=31,ENDBEFR=tab),
city=(FIXLEN=14,ENDBEFR=tab),
state=(FIXLEN=12)),
BUILD=(branch,9:first_name,22:last_name,
38:date,JFY=(SHIFT=RIGHT),
49:company,83:city,98:state)
/*
For complete details on all of the new DFSORT and ICETOOL functions available with the April, 2006 PTFs, see:
www.ibm.com/servers/storage/support/software/sort/mvs/peug/ _________________ Frank Yaeger - DFSORT Development Team (IBM)
Specialties: JOINKEYS, FINDREP, WHEN=GROUP, ICETOOL, Symbols, Migration
DFSORT is on the Web at:
www.ibm.com/storage/dfsort
Back to top
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum