ICETOOL is an IBM utility that uses DFSORT to run multiple operations in a single job step. Instead of writing several steps—one to count records, another to sort, another to copy—you run EXEC PGM=ICETOOL once and list the operations in a TOOLIN dataset. Each operation can use its own DFSORT control statements via a USING(prefix) and a matching prefixCNTL DD. This page introduces what ICETOOL is, when to use it, how the JCL is set up, and the main operators you will see (COPY, SORT, MERGE, COUNT, SELECT, and others).
In a normal DFSORT job you run one program (PGM=SORT or PGM=ICEMAN) and supply one set of control statements in SYSIN. That step does one thing: one SORT, one COPY, or one MERGE. If you need to count records that meet a condition, then sort the same file and write it elsewhere, you would typically use two steps: one that runs DFSORT with INCLUDE and perhaps OUTFIL to get a count or a report, and another that runs DFSORT again to sort and copy. Both steps might read the same input file.
ICETOOL changes that. You run one step with PGM=ICETOOL. In the TOOLIN dataset you list a sequence of operators, such as COUNT, then SORT, then COPY. ICETOOL runs each operation in order. For each operation it can use a different set of DFSORT control statements (in a dataset you reference with USING(xxxx)). So one step can count records with one filter, sort the file with a different SORT FIELDS=, and copy to multiple outputs—all without re-reading the input multiple times in separate steps. That makes the job simpler and can reduce I/O when the same input is used for several operations.
An ICETOOL step has a fixed set of required DDs and then additional DDs depending on which operators you use.
TOOLMSG DD SYSOUT=* or SYSOUT=A. If this DD is missing, ICETOOL can abend or return a high return code (e.g. 20).DFSMSG DD SYSOUT=*. Each time ICETOOL calls DFSORT, DFSORT writes its messages here.TOOLIN DD * for in-stream data and list one operator per line (with optional continuation using a hyphen).In addition, every operator that references an input file needs that DD to be present. For example COPY FROM(INDD) TO(OUTDD) requires an INDD DD and an OUTDD DD. Names are up to you: FROM(MYIN) and TO(MYOUT) require MYIN and MYOUT DDs. Operators that use DFSORT control statements need a prefixCNTL DD when you code USING(prefix). For example SORT FROM(INDD) TO(OUTDD) USING(CTL1) requires a CTL1CNTL DD containing the SORT FIELDS= and any INREC, OUTREC, INCLUDE, etc.
The TOOLIN dataset contains the list of operations ICETOOL should perform. Each line is usually one operator and its parameters. Continuation is indicated by a hyphen at the end of a line. Blanks can appear before the operator and between operands. Common syntax is:
123COPY FROM(INDD) TO(OUTDD) USING(CTL1) COUNT FROM(INDD) USING(CTL2) SORT FROM(INDD) TO(OUTDD) USING(CTL1)
FROM(...) names the input DD for that operation. TO(...) names the output DD for operators that produce an output file (COPY, SORT, MERGE, SELECT, SUBSET, etc.). USING(xxxx) tells ICETOOL to use the dataset allocated to xxxxCNTL as the DFSORT SYSIN for that operation. If you do not need any control statements (e.g. a simple copy with no INCLUDE or OUTREC), you can omit USING and ICETOOL will run DFSORT with minimal or default control.
ICETOOL provides many operators. The table below summarizes the most common ones and what they do. Each operator may have additional operands (e.g. HEADER, TRAILER for DATASORT; FIRST(n) for SELECT); see the IBM ICETOOL documentation for full syntax.
| Operator | Purpose |
|---|---|
| COPY | Copy records from the input DD to one or more output DDs. Uses DFSORT COPY or SORT with control statements in xxxxCNTL if USING is specified. |
| SORT | Sort records from the input and write to output. Requires USING(xxxx) with SORT FIELDS= (and optionally INCLUDE, OUTREC, etc.) in xxxxCNTL. |
| MERGE | Merge multiple input files (e.g. FROM(IN1,IN2)) and write to one or more outputs. Control statements typically include MERGE FIELDS= and OUTFIL. |
| COUNT | Count records (optionally with INCLUDE in xxxxCNTL) and write the count to TOOLMSG or a count dataset. No output file of data records. |
| SELECT | Select records by key (e.g. ON(...) FIRST(n) per key) and write to an output DD. Uses control statements for sort/selection logic. |
| DISPLAY | Compute aggregates (min, max, total, average, count) for numeric fields and write to a list dataset. |
| STATS | Display statistics (min, max, average, total) for specified numeric fields in the input. |
| SUBSET | Copy a subset of records, e.g. exclude or include header/trailer lines (HEADER(n), TRAILER(n), REMOVE/OUTPUT). |
| UNIQUE | Count unique values for a field and write the result to messages or a list file. |
| DATASORT | Sort only the data records between header and trailer; header and trailer are preserved and copied with the sorted data. |
| MODE | Control error handling: STOP, CONTINUE, or SCAN. Affects what ICETOOL does after an operator returns a non-zero return code. |
When you code USING(CTL1), ICETOOL looks for a DD named CTL1CNTL. The name is always the four-character (or longer) prefix you specify in USING, plus the literal CNTL. That DD must contain valid DFSORT control statements. For a SORT operator you would put SORT FIELDS=(...) there, and optionally INCLUDE, OMIT, INREC, OUTREC, OUTFIL, SUM, etc. For a COPY operator with filtering you might put INCLUDE and OUTREC. For MERGE you would put MERGE FIELDS= and OUTFIL. ICETOOL passes the contents of that dataset to DFSORT as if it were SYSIN for that single operation.
You can use different prefixes for different operators in the same step. For example:
12345678910COUNT FROM(INDD) USING(CTL1) SORT FROM(INDD) TO(OUTDD) USING(CTL2) /* //CTL1CNTL DD * INCLUDE COND=(60,2,CH,EQ,C'IN') /* //CTL2CNTL DD * SORT FIELDS=(1,20,CH,A) OUTREC FIELDS=(1,80) /*
Here the COUNT uses CTL1CNTL (only INCLUDE to count records with country 'IN'), and the SORT uses CTL2CNTL (SORT FIELDS and OUTREC). So each operation can have completely different control logic.
A minimal example that just copies input to output with no filtering:
123456789//STEP01 EXEC PGM=ICETOOL //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //INDD DD DSN=MY.INPUT.FILE,DISP=SHR //OUTDD DD DSN=MY.OUTPUT.FILE,DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(5,2)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=27920) //TOOLIN DD * COPY FROM(INDD) TO(OUTDD) /*
TOOLMSG and DFSMSG are required. INDD and OUTDD are the names used in the COPY operator. No USING is needed for a plain copy. ICETOOL will call DFSORT with a simple copy (or equivalent), and the output file will contain the same records as the input.
To count only records that meet a condition, use the COUNT operator with USING and put an INCLUDE in the CNTL dataset:
123456//TOOLIN DD * COUNT FROM(INDD) USING(CTL1) /* //CTL1CNTL DD * INCLUDE COND=(60,2,CH,EQ,C'IN') /*
The count of records where bytes 60–61 equal 'IN' will be written to TOOLMSG (or to a separate count dataset if you specify the appropriate operand). The INCLUDE is applied by DFSORT when ICETOOL runs the COUNT operation.
To sort and copy with a specific key and optional reformatting:
1234567//TOOLIN DD * SORT FROM(INDD) TO(OUTDD) USING(CTL1) /* //CTL1CNTL DD * SORT FIELDS=(6,15,CH,A) OUTREC FIELDS=(1,80) /*
CTL1CNTL contains the real DFSORT control: sort by bytes 6–20 (15 bytes, character, ascending), and write the full 80-byte record. The result is a sorted copy of the input.
ICETOOL sets a return code for each operation and then sets the step return code to the highest one. Common values: 0 (success), 4 (warning), 8 or 12 (e.g. COUNT criteria met and RC8/RC12 specified), 16 (DFSORT error), 20 (TOOLMSG problem). So you can conditionally run later steps based on the ICETOOL return code.
Imagine you have one big pile of papers (your input file). Usually you would ask a friend to do one job: "Count the blue ones," and then in another turn "Sort them by name and put them in this box." ICETOOL is like a helper who can do several jobs in one go. You give them a list: "First count the blue ones, then sort everything by name and put it in that box." They use the same pile once and do both tasks. The list you give is TOOLIN; the extra instructions for each task (e.g. "blue means this exact code" or "sort by these columns") are in the CNTL datasets. So one step, one program (ICETOOL), multiple jobs done in order.
1. What is the main reason to use ICETOOL instead of a single DFSORT SORT step?
2. Where do you put the ICETOOL operator statements (e.g. COPY FROM(INDD) TO(OUTDD))?
3. What does USING(CTL1) mean in an ICETOOL operator like SORT FROM(INDD) TO(OUTDD) USING(CTL1)?
4. Which DD names are required for an ICETOOL step that only runs a COUNT operator?
5. What is the relationship between ICETOOL and DFSORT?