Related
I'm interested in knowing if it is possible to get the contents of a JCL SYSOUT into a z/OS flat file; either in the same JCL step or in a JCL step executed later in the same JCL.
Attention¡, I do not mean the other way round; which is generate the SYSOUT directy in a z/OS file and, after, in another JCL step dump it onto SYSOUT.
For example; in the following JCL step I'm interested in getting the contents of SYSOUT=2 in a flat file.
May anyone shed light in this issue?.
Many thanks in advance.
//WNMPRAD5 EXEC PGM=WNMPRAD5,COND=(4,LT)
//SYSPRINT DD SYSOUT=1
//SYSDBOUT DD SYSOUT=1
//ENTRADA DD DSN=WNMT.SCADUC.WGPT022.ZXDALMA.UNLDBI,DISP=OLD
//SORTIDA DD DSN=WNMT.SCADUC.WGPT022.ZXDALMA.OUTPUT.V02,
// DISP=(NEW,CATLG,DELETE),UNIT=DISK,
// DCB=(RECFM=FB,LRECL=278),
// SPACE=(27998,(2500,2500),RLSE)
//SYSOUT DD SYSOUT=2
//SYSIN DD *
N0100
/*
SYSOUT is no different than any other DD but is used by convention for output. You can create a DD like this in the STEP that creates the file:
//SYSOUT DD DSN=MY.SYSOUT,
// DISP=(NEW,CATLG,DELETE),UNIT=DISK,
// DCB=(RECFM=FBA,LRECL=133,BLKSIZE=0),
// SPACE=(27998,(2500,2500),RLSE)
The DCB will vary depending but 133 (assuming ASA character) is common. No need for a different step.
If you want, you could in a following step use IEBGENER to copy the Disk to another SYSOUT to store the contents in the JOB. Its not possible, as far as I know, to easily grab a SYSOUT in the next step and copy to disk.
Yes. You have to get the LRECL and RECFM correct, but you can get those from the source code to the program you're executing. Most standard reports are 133 and FB or 132 and FBA. I seem to remember IDCAMS was 121 and VBA.
//WNMPRAD5 EXEC PGM=WNMPRAD5,COND=(4,LT)
//SYSPRINT DD SYSOUT=1
//SYSDBOUT DD SYSOUT=1
//ENTRADA DD DSN=WNMT.SCADUC.WGPT022.ZXDALMA.UNLDBI,DISP=OLD
//SORTIDA DD DSN=WNMT.SCADUC.WGPT022.ZXDALMA.OUTPUT.V02,
// DISP=(NEW,CATLG,DELETE),UNIT=DISK,
// DCB=(RECFM=FB,LRECL=278),
// SPACE=(27998,(2500,2500),RLSE)
//SYSOUT DD DISP=(NEW,CATLG,DELETE),
// DSN=&SYSUID..STEPNAME.SYSOUT,
// AVGREC=K,
// LRECL=133,
// RECFM=FB,
// SPACE=(500,(10,10))
//SYSIN DD *
N0100
/*
Provide the disposition parameter and dataset name in the sysout. So, it will be something like
//sysout dd dsn=abc.xyz,disp=(as per your choice)
I'm able to save the UNPAIRED records to SORTOUT (this is what I want) using the following:
//SORT EXEC PGM=SORT,PARM='DYNALLOC=(SYSDA,255)'
//SORTMSGS DD SYSOUT=*
//SORTJNF1 DD DSN=FILE1,
// DISP=OLD,DCB=BUFNO=255
//SORTJNF2 DD DSN=FILE2,
// DISP=OLD,DCB=BUFNO=255
//SORTOUT DD DSN=FILEOUT,
// DISP=(NEW,CATLG,DELETE),
// UNIT=(SYSDA,59),
// SPACE=(CYL,(500,100),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
JOINKEYS FILE=F1,FIELDS=(25,4,A,115,20,A,135,4,A,140,4,A,5,20,A)
JOINKEYS FILE=F2,FIELDS=(5,4,A,9,20,A,29,4,A,33,4,A,37,20,A)
JOIN UNPAIRED,F2,ONLY
but I need to save the PAIRED records to a separate file. I tried the following statement but the PAIRED records don't get saved in my PAIRED file:
//SORT EXEC PGM=SORT,PARM='DYNALLOC=(SYSDA,255)'
//SORTMSGS DD SYSOUT=*
//SORTJNF1 DD DSN=FILE.F1,
// DISP=OLD,DCB=BUFNO=255
//SORTJNF2 DD DSN=FILE.F2,
// DISP=OLD,DCB=BUFNO=255
//SORTOUT DD DSN=FILE.SORTOUT,
// DISP=(NEW,CATLG,DELETE),
// UNIT=(SYSDA,59),
// SPACE=(CYL,(500,100),RLSE)
//PAIRED DD DSN=FILE.PAIRED,
// DISP=(NEW,CATLG,DELETE),
// UNIT=(SYSDA,59),
// SPACE=(CYL,(500,100),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
JOINKEYS FILE=F1,FIELDS=(25,4,A,115,20,A,135,4,A,140,4,A,5,20,A)
JOINKEYS FILE=F2,FIELDS=(5,4,A,9,20,A,29,4,A,33,4,A,37,20,A)
JOIN UNPAIRED,F2,ONLY
OUTFIL FNAMES=SORTOUT
OUTFIL FNAMES=PAIRED,SAVE
Edit 1: OP has mentioned (in the comments section of this answer), "I only want to keep the UNPAIRED records (F2 only) in my main SORTOUT dataset, and the PAIRED records (F2 only) in my PAIRED dataset." Paired records mean both F1 & F2. OP is basically looking for RIGHT JOIN. The SORT statements provided below are edited as per OP's requirement. Note that a REFORMAT statement is required unless a JOIN statement with the ONLY operand is specified.
You must use a method in Syncsort (which is called as indicator method in dfsort), to acheive what you're expecting. See below SORT statements.
SORT FIELDS=COPY
JOINKEYS FILE=F1,FIELDS=(25,4,A,115,20,A,135,4,A,140,4,A,5,20,A)
JOINKEYS FILE=F2,FIELDS=(5,4,A,9,20,A,29,4,A,33,4,A,37,20,A)
REFORMAT FIELDS=(F1:p,l,F2:p,l,?)
JOIN UNPAIRED,F2
OUTFIL FNAMES=BOTH,INCLUDE=(53,1,CH,EQ,C'B'),BUILD=(Build the columns you need from F1/F2)
OUTFIL FNAMES=UNPAIRED,INCLUDE=(53,1,CH,EQ,C'2'),BUILD=(Build the columns you need from F2)
where,
p - The position value indicates the first byte of the field relative to the beginning of the input record.
l - The length value indicates the length of the field.
Observe the ? in the REFORMAT FIELDS statement.
Quote from Syncsort for z/OS Programmer's guide:
?
This symbol is used to place a one-byte indicator in the reformatted
record that indicates whether the reformatted record is a paired or an
unpaired joined record. The indicator will be set to one of three
different printable values:
“B” if the reformatted record is a paired
record
“1” if the reformatted record is an unpaired record created
from the F1 file
“2” if the reformatted record is an unpaired record
created from the F2 file
More details:
Paired and unpaired F1/F2 records (indicator method).
Syncsort for z/OS Programmer's guide.
Hope this helps!
I wish to remove the leading zeros in mm and dd from the following date format yyyy-mm-dd, and hope to get relevant feedback on my attempt.
To illustrate my point, dat=datestr(now-1,'yyyy-mm-dd') ends up with 2016-03-07, However my wish is to retrieve 2016-3-7.
So far I've attempted to work out on a sub-optimal code, leading to 216-3-7.
dat=datestr(now-1,'yyyy-mm-dd');
o=ones(size(result));
z=strfind(dat,'0');
o(zero)=0;
msb=find(mask~=0);
res=dat(msb)
I concede the task is quite tricky, because not all 0s from mm and dd should be removed by default, but only the single-digit mm and dd (let's say from 1-9) which come out with a leading zero when using the datestr() function.
Best,
There is no such forma supported by datestr, you have to use generic functions like sprintf to format it
x=datevec(now-1);
res=sprintf('%d-%d-%d',x(1),x(2),x(3));
Statement: Earlier files were fetched from remote server location to mainframe. Then
those files content were get and saved at mainframe in a sequential file. But
sometime, some file names contained spaces. Due to this job fails while getting its
content.
Now to solve this problem, we fetched all files from server and separated good files
and bad files. Now we fetch only good file contents.
Problem: While renaming the files, we add prefix Process_ and Odate(fetched from Control M) to file name.
But earlier it was done in jcl as below through unix code.
Pseudo code:
print "rename " $1 " " "Process_" %%DAT "_" $1
We are fetching ODATE from a software control-M.
Jcl code:
//JOBNAME JOB (DEE),'Job Desc',CLASS=P,MSGCLASS=J,
// MSGLEVEL=(1,1),COND=(0,NE)
//* %%SET %%DAT = %%$ODATE
//STEP01 EXEC PROC1
PROC1 code:
//STEP02 EXEC PGM=SORT
//SORTIN DD DSN=DS.FILE1,
// DISP=SHR
//SORTOUT DD DSN=DS.FILE2,
// UNIT=SYSSF,
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
// SPACE=(27920,(29,6),RLSE),
// DISP=(NEW,CATLG,DELETE)
//SYSIN DD DSN=DS.PARM(PARM03),DISP=SHR
PARM03 contains:
Here I am creating unix code to rename file:
SORT FIELDS=COPY
OUTFIL BUILD=(1:C'print "get " r_fi',18:SEQNUM, -
3,ZD,22:C'" //DD:upload"',/,1:C'print "rename " r_fi', -
21:SEQNUM,3,ZD,24:C' ', -
25:C' " " "Process_" %%DAT "_" r_fi',53:SEQNUM,3,ZD,80:X)
/*
The unix code which I am creating dynamically:
Here depending on the number of files p_fi01, p_fi02, p_fi03..... is generated.
I am saving the unix code in a dataset and passing it as instream to run.
The problem is, it is not able to get the value in DAT variable.
Is there any way, I can pass the value of D from jcl to proc and append it with
"Process_" using sort card in proc.
Example data:
File File1.csv contents are fetched and then renamed as Process_20140101_File1.csv
Assuming that the rest of your code is OK, it is fairly simple with DFSORT, using JPn, which is a special DFSORT symbol which allows the separate values of up to 10 parameters to be used in control cards.
Here is an example:
// SET INPARM='ABC'
//*
//STEP0100 EXEC PGM=SORT,PARM='JP0"&INPARM"'
//SYSOUT DD SYSOUT=*
//SYMNOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
OPTION COPY
INREC BUILD=(JP0)
//SORTIN DD *
IRRELEVANT DATA, JUST AN EXAMPLE
I have used SET to create a JCL symbol, but you have yours already from CONTROL-M, so just replace &INPARM on the PARM with your CONTROL-M symbol.
JPn means JP0 through JP9. Three separate pieces of data could look like this:
//STEP0100 EXEC PGM=SORT,PARM='JP0"&INPARM1",JP1"&INPARM2",JP2"&INPARM3"'
The SYMNOUNT DD is optional, but very, very useful, as it will show you the translated values of the symbols.
Assuming that the rest of your code is correct, you would make this change:
25:C' " " "Process_"',JP0,C'"_" r_fi',53:SEQNUM,3,ZD,80:X)
And include a PARM on the EXEC card, PARM='JP0"[yourControl-M-symbol]"'
SyncSort does not have JPn, so that is lucky for you that you have DFSORT. A different technique would be required for SyncSort.
I want to create 3 outfiles depending on the below INCLUDE criteria from the input file. In addition I want only part of the record in the output file given by the below 3 BUILD's.
The issue now I think is that having multiple BUILD/OUTREC gives a duplicate error.
Is there any other way of achieving the same in JCL?
SORT FIELDS=COPY
OUTFIL FILES=01,
INCLUDE=(38,8,CH,EQ,C'AMSAM00'),
BUILD=(1,4,5:366,8)
OUTFIL FILES=02,
INCLUDE=(38,8,CH,EQ,C'AMSAM00',AND,390,1,CH,EQ,C'Y'),
BUILD=(1,4,5:382,8)
OUTFIL FILES=03,
INCLUDE=(38,8,CH,EQ,C'AMSAM00',AND,545,4,CH,NE,C'0000'),
BUILD=(1,4,5:C'013,',9:545,4)
This got a random poke, so...
Deuian I think was on the right lines, but left some complication and for user change didn't use the correct positions or type of output file, so would have been too much typing to apply to the situation...
OPTION COPY
INCLUDE COND=(38,8,CH,EQ,C'AMSAM00')
OUTFIL FILES=02,
INCLUDE=(390,1,CH,EQ,C'Y'),
BUILD=(1,4,382,8)
OUTFIL FILES=03,
INCLUDE=(545,4,CH,NE,C'0000',
AND,390,1,CH,NE,C'Y'),
BUILD=(1,4,C'013,',545,4)
OUTFIL FILES=01,SAVE,
BUILD=(1,4,366,8)
This presumes that SORTOUT will not be needed (it would just be a copy of the input file).
All the AMSAM00 records are INCLUDED, everything else (which is unwanted for the OUTFILs) is ignored.
OUTFIL 02 gets all the 'Y's.
OUTFIL 03 gets all the not 0000s which are not 'Y'
OUTFIL 01, moved to make it easier to follow, gets all the records which are not selected on another OUTFIL (by using SAVE).
All of the data which passes the INCLUDE will be on one of the three OUTFILs, and only one.
I have used OPTION COPY for clarity. SORT FIELDS=(... logically appears after the INCLUDE (wherever you code it) and by using OPTION COPY it is clear, up front, and in a logical place, that it is a COPY operation.
I have taken out the "columns" from the BUILDs (those numbers followed by a colon). If the data is going into that column automatically (which it is), then using the columns only creates work, introduces a new possibility of error, and makes the Sort Control Cards more difficult to maintain.
The question is unclear, so this is just a guess at what was wanted.
There was mention of OUTREC.
From the context, this is OUTREC on OUTFIL. There is a separate OUTREC statement. To avoid confusion (due to the "overloading" of OUTREC), don't use OUTREC on OUTFIL, which is for "backwards compatability", use the modern BUILD instead, which is entirely equivalent.
BUILD exists on INREC, OUTREC and OUTFIL, separately and as part of an IFTHEN. OUTREC as equivalent of BUILD is only on OUTFIL.
On INREC and OUTREC, FIELDS also has the "overloading" for the same reason (the backwards thing).
Don't use INREC FIELDS=, or OUTREC FIELDS= or OUTFIL OUTREC=, use BUILD in their place.
The below is what I think you are trying to do. Include 1 excludes what Include 2 and 3 will select, likewise Include 2 excludes what 1 and 3 will select. Include 3 is doing the same except excluding 1 and 2 includes.
Each FILE DD has only 1 record from the below and all the records are copied to the sortout
//SORTIN DD *
AMSAM00Y0000
AMSAM00N0001
AMSAM00Y0001
AMSAM00N0000
//SORTOUT DD SYSOUT=*
//SYSIN DD *
SORT FIELDS=COPY
OUTFIL FNAMES=FILE1,
INCLUDE=(1,7,CH,EQ,C'AMSAM00',
AND,8,1,CH,NE,C'Y',AND,9,4,CH,EQ,C'0000'),
BUILD=(1,12)
OUTFIL FNAMES=FILE2,
INCLUDE=(1,7,CH,EQ,C'AMSAM00',AND,
8,1,CH,EQ,C'Y',AND,
9,4,CH,EQ,C'0000'),
BUILD=(1,12)
OUTFIL FNAMES=FILE3,
INCLUDE=(1,7,CH,EQ,C'AMSAM00',AND,
8,1,CH,NE,C'Y',AND,
9,4,CH,NE,C'0000'),
BUILD=(1,12)
FIlE1
AMSAM00N0000
FILE2
AMSAM00Y0000
FILE3
AMSAM00N0001
SORTOUT
AMSAM00Y0000
AMSAM00N0001
AMSAM00Y0001
AMSAM00N0000