Mainframe records often contain binary fields or flag bytes—single bytes or halfwords that encode status, options, or bit flags. Filtering on these fields in DFSORT is done with INCLUDE or OMIT and COND= by using the BI (binary) format. BI tells DFSORT to interpret the specified bytes as a binary integer (unsigned or signed depending on length and product), so you can compare them to numeric constants using EQ, NE, GT, GE, LT, or LE. There is no separate "bit test" operator in the basic COND= syntax; you test the value of the field. So "keep records where the flag byte equals 1" is (start,1,BI,EQ,1). If your data uses a single byte where each bit has a meaning, you can still filter by comparing to a constant that has the desired bit set (e.g. 4 for "bit 2 on") when that is sufficient; some DFSORT products also support a BT (bit test) format for testing individual bits—check your IBM DFSORT Application Programming Guide. This page covers using BI for binary and flag-byte filtering, the difference between BI and CH for numeric-looking bytes, and combining bit-style conditions with AND/OR.
In COND=, the third element of each condition is the format. For fields stored in binary (fullword, halfword, or single byte as an integer), use BI. The syntax is the same as for CH or PD: (start, length, BI, operator, constant). Start is the starting byte position (1-based). Length is the length of the field in bytes—typically 1 for a flag byte, 2 for a halfword, 4 for a fullword. Constant is a numeric value (e.g. 0, 1, 255). DFSORT interprets the bytes at start for length bytes as a binary number and compares it to the constant. Example: keep records where a 2-byte binary field at position 60 is not equal to 0:
1INCLUDE COND=(60,2,BI,NE,0)
So any record with a non-zero value in that halfword is kept. To omit records where that same field is zero:
1OMIT COND=(60,2,BI,EQ,0)
The operators EQ, NE, GT, GE, LT, LE all work with BI; the comparison is numeric (integer).
A common case is a single byte used as a flag: 0 = off, 1 = on (or other numeric codes). Use length 1 and BI:
1INCLUDE COND=(20,1,BI,EQ,1)
This keeps records where the byte at position 20 has the value 1 (x'01' in hex). If the flag uses multiple values (e.g. 0=invalid, 1=active, 2=pending), you can keep more than one with OR:
1INCLUDE COND=(20,1,BI,EQ,1,OR,20,1,BI,EQ,2)
So records with flag 1 or 2 are kept. Alternatively, omit the unwanted value: OMIT COND=(20,1,BI,EQ,0) keeps all non-zero flags.
A byte that "looks like" a number can be stored in two ways: as a binary value (e.g. 1 stored as x'01') or as a character digit (e.g. 1 stored as EBCDIC x'F1', the character '1'). If you use BI and constant 1, DFSORT compares the byte to x'01'. If you use CH and C'1', it compares to x'F1'. So you must match the format to how the data is actually stored: use BI for binary flag bytes and integers, and CH for character digits or text. Using the wrong format will give wrong results (e.g. BI,EQ,1 will not match character '1').
When a byte is used as a set of bits (bit 0, bit 1, …), each bit can represent a yes/no flag. In basic COND= there is no "test bit N" operator. Two approaches: (1) If the only thing you care about is one bit and the rest of the byte is zero or ignored, you can compare the whole byte to the numeric value that has that bit set. For example, "bit 2" (third bit) has value 4 (2^2). So INCLUDE COND=(20,1,BI,EQ,4) keeps records where the byte equals 4—i.e. only bit 2 is set. (2) If you need "bit 2 set" regardless of other bits, you need a way to test that bit. Some DFSORT versions support a BT (bit test) or similar format; see your IBM DFSORT documentation. Otherwise you may need a user exit or INREC to isolate the bit. We document the constant-equality approach here because it works with standard COND= and is sufficient when the byte is used as a single-value code.
| Format | Meaning | Typical use |
|---|---|---|
| BI | Binary; integer value of the bytes | Flag bytes, halfwords, fullwords, any binary integer |
| CH | Character (EBCDIC) | When the byte is stored as character digit or letter |
| PD/ZD | Packed/zoned decimal | When the field is decimal numeric, not binary |
You can combine BI conditions with AND and OR like any other condition. Example: keep records where flag1 (position 20, 1 byte) is 1 and flag2 (position 21, 1 byte) is 0:
1INCLUDE COND=(20,1,BI,EQ,1,AND,21,1,BI,EQ,0)
Or keep records where a 2-byte status at 40 is either 10 or 20:
1INCLUDE COND=(40,2,BI,EQ,10,OR,40,2,BI,EQ,20)
The same continuation and parenthesis rules as for other INCLUDE/OMIT conditions apply.
Imagine a light switch: it can be off (0) or on (1). The computer stores that as one tiny number: 0 or 1. When we want to keep only the "on" records, we tell the sort: "keep only the records where this tiny number is 1." That's bit testing in the simplest form. Sometimes one byte has several switches (bits); each can be 0 or 1. Then the byte is like a number made of those bits (e.g. 4 means "the third switch is on"). We can say "keep records where that number is 4" to mean "keep when that one switch is on." We use "BI" so the computer knows we mean the real number (binary), not the character we type on the keyboard.
1. How do you keep records where a 2-byte binary field at position 50 equals 0?
2. What format do you use in COND= to compare a field as raw binary (not packed or zoned decimal)?
3. If a single byte at position 20 is used as a flag (0=off, 1=on), how do you keep only records where the flag is on?
4. How might you keep records where a specific bit in a byte is set, if your DFSORT does not support a BT format?
5. Can you use AND/OR with bit-style conditions in INCLUDE?