MVS TOOLS AND TRICKS OF THE TRADE SEPTEMBER 2006 Sam Golob MVS Systems Programmer P.O. Box 906 Tallman, New York 10982 Sam Golob is a Senior Systems Programmer. He also participates in library tours and book signings with his wife, author Courtney Taylor. Sam can be contacted at sbgolob@cbttape.org. Information about the CBT MVS Tapes can be found on the web, at http://www.cbttape.org. FIND AND REPLACE IN PLACE A large part of our job concerns the manipulation of files. Some of the work involves the moving of files from one place to another. But another piece of what we do, is to make sure that the contents of system files, libraries, and even directories (pds directories, VTOCs, and so forth) are (either) what they should be, or what you want them to be. Today, we shall talk about the process of looking for character strings in one or multiple files, and if need be, changing them to some other string. This process is often not as simple as just editing the file, and as we shall see, there's sometimes quite a bit more to it. Usually, if we want to change a character string in a file, editing the file is enough. When you edit a pds member and save the edit, you create a new copy of the member (in the free space at the end of the pds member data) and you re-point the pds directory entry for that member, to the TTR at the beginning of the new copy. This leaves the data of the old copy intact, but not pointed to, until the next "compress operation" on the pds. And a by-product of this editing operation is that extra disk space is used up in the pds. On the other hand, if a purely physical sequential file is being edited (i.e. NOT a pds member), and the changes are saved, then it may depend on how the specific editor works, but the usual result is that the new copy of the file is written over all of the disk space where the old file existed before. Again, as with the case of merely editing pds members, this may not present any real problem to us, because we don't care exactly where each data block of the file resides on the disk. But sometimes we do care, and it just may be, in a case of a specific find-replace, that we want to only replace the minimum of the file data (usually an individual data block) that it is possible to replace. So we need to have tools to do this. For example, if we need to zap a VTOC entry on a disk pack, it is very critical that the new data reside in the same place where the old data was. The CCHHR of the beginning of the VTOC is pointed to by the volume label of the disk pack, and the VTOC cannot be moved noninvasively, under ordinary circumstances, except through the use of specialized tools. So any tool which is used to merely change a VTOC entry, must only replace the minimum amount of data, and it should be capable of doing a "replace in place" of any data block in the file. TOOLS THAT CAN DO "REPLACE IN PLACE" For the purposes of this column when it comes to tools, I prefer to discuss either tools that are shipped for no extra cost with the MVS operating system, or if the tools are indeed "add-on" to MVS, they should be obtainable for free. Although sometimes vendor tools (which can cost a lot of money) will do the same job as well, they are not in everybody's MVS shop, and if I write about them, most of the people will say that "this procedure or technique is not for me." So I certainly want to avoid such a scene. That's why I mention free tools all the time. Free tools can be obtained and profitably used by anyone who reads this column and who has access to an MVS machine. The principal tools I'll discuss today are free "add-on" tools which are obtainable from the CBT Tape website. You don't need a password to get any of these tools from the CBT website. Just do a www.google.com search for "CBT Tape" and the website should come out near the top of the search. The two main tools I want to talk about, are "Fullscreen ZAP" (source on CBT File 134, load module on File 135) and the PDS 8.6 program package (source, panels and message members on CBT File 182, load module (if you don't assemble it yourself) on File 035). As we discussed last month, sometimes you can get the latest version of CBT Tape programs by going to the Updates page of the CBT website, as opposed to the CBT page. As of this writing, the latest version of the PDS 8.6 package is on File 182 of the Updates page. FULLSCREEN ZAP Fullscreen ZAP is TSO command which is a replacement for IBM's AMASPZAP program, but it has the enormous advantage of showing you the data on screen, both before and after a string replacement has been made. You get to see 256 bytes of the data at a time, and in addition, Fullscreen ZAP shows you much of the detail about where the data is, and what kind to physical blocking it has, right at the bottom of the screen. Fullscreen ZAP only does a "replacement in place" of the current block of data, so it is quite uninvasive to the file being manipulated. For ordinary data replacement to a file, Fullscreen ZAP doesn't even have to be APF authorized. But if you want to use Fullscreen ZAP's enormously powerful FULLVOL option, which zaps the DEB of the data file to change its extents to those of the entire pack, then the ZAP command has to be APF authorized, as a TSO command, and its name has to be entered in the effective IKJEFTE2 table for that MVS system. (Edit the AUTHCMD NAMES entries of the IKJTSOxx member of PARMLIB to include the name ZAP, do a PARMLIB UPDATE(xx) TSO command, or a SET IKJTSO=xx operator command. More advanced techniques for APF authorizing a TSO command have been mentioned from time to time in this column.) Of course the ZAP load module has to be link-edited with SETCODE AC(1). If you forgot to do that, the PDS 8.6 program (to be mentioned later) is capable of setting the AUTH bit on in ZAP's load module directory entry, by pointing the PDS command to the load library, and using the ATTRIB ZAP AUTH subcommand on the ZAP load module. Fullscreen ZAP does not need ISPF. It works under raw TSO. And Fullscreen ZAP has it's own online help. Once you enter the ZAP command against a dataset (with the optional VOL() operand if the dataset is not cataloged), then entering the word HELP, or a question mark (?) in the upper left hand corner command area will give you 13 help screens that scroll forward each time you press ENTER. To get back to where you were working before, just enter U in the command area of the help screen. To ZAP a VTOC for a particular volume, use the VOL() parameter, and make the dataset name 'FORMAT4.DSCB'. Finding data with Fullscreen ZAP can be done either in HEX or in EBCDIC. To use ZAP's FIND command (F) for hex data, just enter the hex data after the subcommand F with no spaces in between. To find EBCDIC data, just enclose the data in between slashes or question marks. Again, don't put a space between the F and the data. Try it. You'll like it. If you're not using ZAP in FULLVOL mode, the F subcommand will stop it's action when you've reached the end of all the dataset's extents, if you haven't found the string. If you are using the FULLVOL option, it is obvious that ZAP will find all occurrences of the string on the DASD, in CCHHR order from the start of the search, and it will even find the string in deleted data areas. So you see that you can search deleted data on DASD using Fullscreen ZAP by using the FULLVOL option. Replacing EBCDIC data with ZAP unfortunately requires a knowledge of EBCDIC character representation, because ZAP will only accept replacement data (using its S subcommand) if you enter (up to 8 bytes of) hex data immediately after the S in the command area. You can also OR and AND existing data using other ZAP subcommands, but the data entry is always in hex. So ZAP requires (at least) some skill with hex numbers to be used effectively, when data is to be replaced in a block. From my own experience, you get the most joy and effectiveness from the ZAP command by playing with it, and trying the different subcommands that are mentioned in the built-in HELP. Then, once you've seen the possibilities, you'll almost never go back to AMASPZAP, unless you need to set up a batch job. In fact, when setting up such a batch job with AMASPZAP, you can explore the relevant disk area using Fullscreen ZAP first, to actually see the data and verify that it is what it is supposed to be. For zapping disk data, Fullscreen ZAP is always my first choice. IBM's AMASPZAP is a very distant second choice, and I only use AMASPZAP when I absolutely have to. FIND AND REPLACE WITH THE PDS COMMAND The free PDS TSO command (which can either be run under Raw TSO using the XISPMODE option, or under ISPF), is a multipurpose tool that contains something like 1000 separate functions which are grouped under perhaps 60 subcommands. But the reason why we are mentioning it here, this month, is because its default FIND-REPLACE mechanism uses the "replace in place" technique. And you can use the PDS command to do multiple (read "up to hundreds" or "thousands") of find-replace operations at one time. Clearly, when you know how to use the PDS command in this way, it is an enormous time saver. Of course, you have to be careful and accurate too, and not replace a string that shouldn't be replaced. I assume that an MVS sysprog with reasonable skills is appropriately safety minded concerning his or her employer's data. Unlike the Fullscreen ZAP command, the PDS command (even though it is also a TSO command) can also be made to run under TSO-in-batch. So you can set up batch jobs to use the PDS command and accomplish what you want to do. And under ordinary circumstance, the PDS command is designed NOT to run APF-authorized. So that is another advantage which PDS has. When using the PDS command to FIND character strings and subsequently REPLACE them, you can do a dry run of the REPLACE command, which will not make any actual changes. Then, when you've carefully looked at the results of the dry run, and adjusted it appropriately so it is exactly right and it does exactly what you want, you can then execute the same REPLACE command with the WRITE option, and make the changes in-place and final. The syntax of the FIND subcommand and REPLACE subcommand in PDS are quite simple. For FIND, you have a space after the command, and you enclose the desired (EBCDIC) string between a delimiter character such as a slash or a question mark. So to find all occurrences of the string ABCDEFG in all the members of an entire pds, you would point the PDS command to the partitioned dataset by saying: PDS my.dataset and then you'd run the subcommand: FIND : /ABCDEFG/ (where the colon (:) stands for "all members') which would produce a report in the PDS log, showing all occurrences of the EBCDIC string ABCDEFG in the entire pds. To do a replacement of ABCDEFG with HIJKLMN, you'd use the PDS REPLACE subcommand as follows: REPLACE : /ABCDEFG/HIJKLMN/ If the "find" or "replacement" string of data contains lower case characters, use the ASIS option of FIND or REPLACE to avoid upper-casing. To FIND or REPLACE hex data, enclose the hex data between the character x, as a delimiter. In other words, FIND : xFFx which will find all occurrences of X'FF' in all members of the pds. All the REPLACE operations of the PDS command use the "replace-in-place" technique, and no additional free space is used up. If the replacement string is longer then the "find" string, overflow conditions are shown in the PDS log report which contains the results of the command. So it is always best to do a "dry run" and not use the WRITE option until you are absolutely ready to make all the changes final. I don't have too much space left here, but I must mention that the PDS command allows selection of "member subgroups" which are referred to by entering an asterisk (*) in the place where you put in the member name in any PDS subcommand. The FIND subcommand of PDS has THEN and ELSE operands, which can be used as follows: FIND : /ABCDEFG/ THEN(SUBLIST) This will allow you to pick a subset of all partitioned dataset members which contain the string ABCDEFG and ONLY those members. So you can select a subgroup of only those members containing the given string, and conveniently refer to that subgroup using the character "*". Thus, after the above FIND command, you can later enter: REPLACE * /ABCDEFG/HIJKLMN/ and know, positively, that you have affected only the members which actually contain the string, and not any other members of the partitioned dataset. As you can see, if you explore the HELP member of the PDS command, that the possibilities are almost endless, and once you have the experience, you can do a lot of FIND and REPLACE work in very little elapsed time. If you look in the PDS HELP at the DATA subcommand of the LIST subcommand, you will see even more power, that you've never even dreamed of. I say again: Try it. You'll like it. But, BE VERY CAREFUL..... SUMMARY Today, we've explored some possibilites concerning finding character strings in data, and replacing them in place. These techniques use free and powerful MVS tools which run under TSO. So everybody with an MVS system can run them. However, to properly use these tools requires quite a bit of practice and experience. But if you've put in the time, you'll reap the rewards, and you'll thank me many times over. I wish you a lot of luck and success in all your endeavors, and I'm looking forward to seeing you here again next month.