I have a requirement to read 5 (# delimited) Variable length files as input and create one single output file containing 5 records, each record corresponding to one input file with following information in Output record:
<<filename 10 bytes>> <<Count (excluding Header record) 8 bytes>> <No of delimiters '#' appearing in header record of each file 5 bytes>>
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
I'm not sure that counting the delimiters is "easy", particularly if more than 100 (if more than 100 PARSE will not come to your aid). You have a five-byte count, but what is your maximum number?
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
Puneet,
after 9 topics in DFSORT/ICETOOL started by you,
what info do you think we need?
i would say it is incumbent upon you
to at least search the forum
and determine what info we may need
to do your work for you so that you can keep your job.
1. Each input file is # delimited and of variable length VB= 560 bytes
2. There is no indicator text to identify the Header record. It would be the first record in each file.
3. Output file length required = 80 Bytes FB.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
:-)
I understood all that a while ago. I was trying to give you some pointers for how you go about it.
From the link dbz required you to read, you can count the hash signs (for your headers).
Counting records on the files is easy with ICETOOL's COUNT operator.
The "hard coded" names are the easiest part.
Then you have to bring all that together to create your output file with five records on it.
Since you are keeping other relevant information close to you, I'm assuming that you're going to pick up the task and run with it to completion.
If not, think about the information anyone else would need to do the task. Like how are the headers identified? Is there anything unique to the file on the header? Are the files all the same RECFM? Same LRECL? Does your site allow use of ICETOOL for the task? What is the "one step" thing about? Anything else you can think of, without just repeating what you've already said?
No, since file is of variable length (max LRECL=556 + 4 Bytes) total = 560 bytes. it does not mean that header continue till 556 position.
1. All input file are of different LRECL and are variable length files.
2. want this task to be done in only ONE STEP of Jcl.(if possible)
3. Header is to be identified as the first record appearing in the file. There are no specific Indicators in the HEADER part of each file.
4. No trailers in Input files.
5
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
well, maybe this logic could be used to count the delimiters.
unfortunately i don't have access to mainframe, so i can not dev and test:
header record, max 556
so you need a 'if it is a short record, deal with it parm' in you control card
Quote:
2 ICETOOL Processing Steps per file
ctl1 TO pull a header, parse out each '#', creating 1 record for each
ctl2 only include records with '#', and generate a trailer with the count
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
as it was pseudo code and not code (per se)
and it was easier to read with elixir tags (though i did refrain from color codes)
than with code tags, i decided to go with quote tags.
Now, the idea is, if this is a "hash-seperated-variables" file that probably means it is a text file. So, just needs lots of repeats of the "C'B'," line, then replaced by remaining letters of the alphabet, numbers and keyboard characters.
I was also thinking that if the "header" is actually some sort of header, the only thing headery about it will be column-titles. Meaning that the last record on the file will be equally useful for knowing how many "columns" are in the data. May or may not be of use to any further solution elements. Should be San Jose time soon anyway...
Joined: 07 Dec 2007 Posts: 2205 Location: San Jose
Ideally I would use an exit to count the delimiters and DFSORT to count the records in each file. Since the input files are VB , you can simply concatenate them and find the counts. There is nothing unique to distinguish the headers , so we create a dummy file to generate the headers.
IDENTIFICATION DIVISION.
PROGRAM-ID. DLMCOUNT.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-DLM-COUNT PIC 99999.
LINKAGE SECTION.
01 RECORD-FLAGS PIC 9(8) BINARY.
88 FIRST-REC VALUE 00.
88 MIDDLE-REC VALUE 04.
88 END-REC VALUE 08.
01 IP-RECORD PIC X(557).
01 OP-RECORD PIC X(557).
PROCEDURE DIVISION USING RECORD-FLAGS
, IP-RECORD
, OP-RECORD.
IF END-REC
MOVE 8 TO RETURN-CODE
ELSE
IF IP-RECORD (1 : 1) = 'H'
MOVE 0 TO WS-DLM-COUNT
INSPECT IP-RECORD TALLYING WS-DLM-COUNT FOR ALL '#'
MOVE 4 TO RETURN-CODE
ELSE
MOVE IP-RECORD(2:80) TO OP-RECORD(1:80)
MOVE WS-DLM-COUNT TO OP-RECORD(20:5)
MOVE 20 TO RETURN-CODE
END-IF
END-IF
Joined: 15 Feb 2005 Posts: 7129 Location: San Jose, CA
Here's a way to do it without the exit or the added $$$ separators. I incorporated Bill's character counting code, which is quite clever. I decided to use an extra pass to handle IN1, IN2, etc rather than repeating all of the control statements each time to use 'IN1', 'IN2', etc.
Joined: 15 Feb 2005 Posts: 7129 Location: San Jose, CA
Bill sent me a better version of his trick offline (thanks, Bill). He realized we could just remove the target characters and then get the number of those characters from
original length of record - new length of record
Hopefully, he'll post the general version of his trick here.
I've incorporated his trick into my solution and it makes it much simpler. Here's the revised version:
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Thanks Frank.
When I can, I'll make it look a bit neater, with SYMNAMES, but my connection is "up the wall" at the moment...
Two things to bear in mind:
It is "destructive", in that the data being counted no longer exists.
Only works with variable-length records, as it relies on the RDW being present
First, build a record, RDW, original record-length from the RDW, the rest of the record
Second, do the FINDREP for the character (multiple are possible if needed) being counted - the located character is made to disappear by DFSORT (the C'' bit) and the record-length in the RDW is automatically adjusted.
Third, calculate the difference between the original saved record-length and the current record-length. The adjustment for +2 is to take account of the two-byte extension of the record to include the original record-length.
The STARTPOS=7 on the FINDREP is to make sure nothing from the RDW or the original record-length is touched, it is the first byte of the actual data.
Since the FINDREP IN are no longer generated, no need to have a hex literal, just whatever is needed in plain text is fine.
Since the record has been destroyed, there is no problem with just putting the final count over the start of the remaining data.
If this needs a name, it is called Humphrey, my son's cat, in memoriam