REXX: Find a String In a PDS
One of the first utilities I wrote using REXX in a MVS TSO environment was a simple program to search a named PDS (partitioned data set) for a specified string. The program accepts two inputs: the name of the PDS to be searched and the string to search for. It then writes the search results to an output file for subsequent browsing.
Following is a sample session that illustrates the program in operation. Table 1 shows the screen dialog that goes on between the user and the program. Note that in this session I have "forgotten" to provide the command line paramters. Bold face text are my inputs to the program.
Table 1. Screen Session Input and Output
===> ex showstr2 Error: You did not specify a dataset ------------------------------------ Enter name of PDS to search: p.sas Error: You did not specify a string. ------------------------------------ Enter the string to find: compress( member=myuserid.P.SAS($AATEST) member=myuserid.P.SAS($ADOCLOC) member=myuserid.P.SAS($ALLOC) member=myuserid.P.SAS(WS9605X) member=myuserid.P.SAS(X#MERGE3) member=myuserid.P.SAS(XMIT) member=myuserid.P.SAS(XMIT2) member=myuserid.P.SAS(XPROC) member=myuserid.P.SAS(ZERO) *** SEARCH COMPLETE *** |
In this version of the program, the output file name is hard coded. Let's take a look at Table 2 which is a listing of the output file's contents following the search.
Table 2. Report File Output
------------------------------------------------ --- Searching P.SAS for string < COMPRESS( > ------------------------------------------------ ------------------------------------------------ ----> $EXAMPLE has the string < COMPRESS( > VARIABLE=COMPRESS(VARIABLE,'CHARS_TO_REMOVE'); VARIABLE=COMPRESS(VARIABLE,'CHARS_TO_REMOVE'); VARIABLE=COMPRESS(VARIABLE); /* THIS REMOVES ALL BLANKS */ DO; MB_PRNT=COMPRESS((MB_NAME || SUBSTR(AVALU,NDX,1))); ------------------------------------------------ ----> #PUT has the string < COMPRESS( > COLNUMS=COMPRESS(FORM,'$ACDHMOPRYZ'); COLNUMS=COMPRESS(FORM,'$ACDHMOPRYZ'); ------------------------------------------------ ----> #SAMPLES has the string < COMPRESS( > MB_PRNT=COMPRESS((MB_NAME || SUBSTR(AVALU,NDX,1))); MB_PRNT=COMPRESS((MB_NAME || SUBSTR(AVALU,NDX,1))); ------------------------------------------------ ----> CODETEMP has the string < COMPRESS( > XMSG=COMPRESS(XMSG) || 'CABS'; XMSG=COMPRESS(XMSG) || 'CABS'; XMSG=COMPRESS(XMSG) || ',NICD'; XMSG=COMPRESS(XMSG) || '>'; ------------------------------------------------ ----> MAKCSV has the string < COMPRESS( > SID=COMPRESS(SID); SID=COMPRESS(SID); ------------------------------------------------ ----> VERIFY has the string < COMPRESS( > ID=COMPRESS(ID); ID=COMPRESS(ID); ------------------------------------------------ -------------- END OF SEARCH ------------------ ------------------------------------------------ |
As you can see, the program identifies the PDS member that the string was found in and prints out the line in which the string was found.
Now that you've previewed a sample session and the program's report output, here is the REXX program source code. Use this code to further your understanding of how REXX works in an MVS TSO environment. Be forewarned that you use this code at your own risk and I make no guarantees that it will work on your system.
Complete REXX Program Source Code
001 /** REXX **/ 002 /** NAME: SHOWSTR2 **/ 003 /** TASK: test writing results to a file **/ 004 /** PARM: STRING TO FIND **/ 005 /** CMD: STR2FND pdstosearch stringtofind **/ 006 /** **/ 007 /**----------------------------------------------------------------**/ 008 /**step00: Move command line parameters into variables **/ 009 arg pdsname str2fnd 010 /**----------------------------------------------------------------**/ 011 /**step01: Test for parameters **/ 012 /**----------------------------------------------------------------**/ 013 if pdsname = "" then 014 do 015 say "Error: You did not specify a dataset" 016 say "------------------------------------" 017 say 'Enter name of PDS to search:' 018 pull pdsname 019 end 020 if str2fnd = "" then 021 do 022 say "Error: You did not specify a string." 023 say "------------------------------------" 024 say 'Enter the string to find:' 025 pull str2fnd 026 end 027 /**----------------------------------------------------------------**/ 028 /**step02: Test for PDS existence **/ 029 /**----------------------------------------------------------------**/ 030 if sysdsn(pdsname) <> "OK" then 031 do 032 say "Error: Specified PDS not found:" pdsname 033 say "Error: " pdsname " > " sysdsn(pdsname) 034 say "Press Enter to continue" 035 pull uresp 036 exit 8 037 end 038 /**----------------------------------------------------------------**/ 039 /**step03: Invoke OUTTRAP to capture the LISTD program output **/ 040 /** NOTE: this works because LISTD uses PUTLINE for output **/ 041 /**----------------------------------------------------------------**/ 042 call outtrap "mbrs." 043 /**----------------------------------------------------------------**/ 044 /**step04: Call the LISTD program to get the member list **/ 045 /**----------------------------------------------------------------**/ 046 "LISTD" pdsname "MEMBERS" 047 /**----------------------------------------------------------------**/ 048 /**step05: Turn off outtrap **/ 049 /**----------------------------------------------------------------**/ 050 call outtrap "off" 051 /**----------------------------------------------------------------**/ 052 /**step06: identify point at which the member list starts **/ 053 /** this will be the value in ndx **/ 054 /** say 'test - there are ' mbrs.0 ' members' **/ 055 /**----------------------------------------------------------------**/ 056 do ndx=1 to mbrs.0 057 if mbrs.ndx = "--MEMBERS--" then leave 058 end 059 ndx=ndx+1 060 /**-----------------------------------------------------------------**/ 061 /**step04: open the file to write the output to **/ 062 /**-----------------------------------------------------------------**/ 063 "ALLOC FI(XXOUT) DA('JPLAXCO.PRINT') MOD REUSE" 064 IF RC \= 0 THEN 065 DO 066 SAY '*** ERROR - LOG ALLOCATION FAILED: ABENDING' 067 EXIT 0 068 END 069 /**-----------------------------------------------------------------**/ 070 /**step07: Convert the pdsname to make sure it is fully qualified **/ 071 /** This adds the high level qualifier, if needed **/ 072 /**-----------------------------------------------------------------**/ 073 call listdsi pdsname 074 fullname=sysdsname 075 /**-----------------------------------------------------------------**/ 076 /**step07: Search each member for the string **/ 077 /** parse copies the data in mbrs.x into the memname variable**/ 078 /** strip removes leading and trailing blanks **/ 079 /** EXECIO is the REXX funtion to read+write files **/ 080 /** * means process all records in the file **/ 081 /** DISKR specifies Read **/ 082 /** XXIN is the DDname to read from **/ 083 /** ( says additional parms follow **/ 084 /** FINIS says to close the DD when finished **/ 085 /** STEM says to read the records into a stem var. **/ 086 /** IN. is the name of the stem variable **/ 087 /**-----------------------------------------------------------------**/ 088 lot.1="------------------------------------------------" 089 lot.2="--- Searching " pdsname " for string <" str2fnd ">" 090 lot.3="------------------------------------------------" 091 lot.0=3 092 "EXECIO" lot.0 "DISKW XXOUT (STEM lot." 093 do curmbr = ndx to mbrs.0 094 parse value mbrs.curmbr with memname 095 memname=strip(memname) 096 hdr=1 097 say "member="fullname"("memname")" 098 "ALLOC F(XXIN) DS('"fullname"("memname")') SHR REUSE" 099 "EXECIO * DISKR XXIN (FINIS STEM in." 100 "FREE F(XXIN)" 101 fnd=0 102 do recid=1 to in.0 103 if pos(str2fnd,in.recid) > 0 then 104 do 105 if hdr = 1 then 106 do 107 lot.1="------------------------------------------------" 108 lot.2="----> " memname " has the string <" str2fnd ">" 109 lot.3 = in.recid 110 lot.0=3 111 "EXECIO" lot.0 "DISKW XXOUT (STEM lot." 112 hdr=0 113 end 114 lot.1 = in.recid 115 lot.0=1 116 "EXECIO" lot.0 "DISKW XXOUT (STEM lot." 117 end 118 end 119 end 120 say '*** SEARCH COMPLETE ***' 121 lot.1="------------------------------------------------" 122 lot.2="-------------- END OF SEARCH ------------------" 123 lot.3="------------------------------------------------" 124 lot.0=3 125 "EXECIO" lot.0 "DISKW XXOUT (STEM lot." 126 "EXECIO 0 DISKW XXOUT (FINIS" 127 "FREE F(XXOUT)" 128 exit 0
Return to the Mainframe section index.
Copyright ©1999-2023, Astrodigital, http://www.astrodigital.org. All rights reserved. Direct questions, problems and update notification requests to Contact