View previous topic :: View next topic
|
Author |
Message |
kbrahma
New User
Joined: 08 Oct 2007 Posts: 38 Location: Delhi
|
|
|
|
Hi All,
I have to code a REXX which reads the contents of a member and then finds a string in it. When it finds that string it has to copy all the contents written below it. Currently my rexx only copies a single string and writes it to the PDS member (by using the PUSH command).
I wanted to know how can I write multiple lines (following my string) into the member I am creating (other than passing the PUSH command several times with different variable names and increasing the lines positional parameter).
The REXX I coded can only write a single string after the string it searches (in variable indd.i corresponding to the counter "i"]), how can I make it to write all the lines after the string is found..
Code: |
do
"alloc shr fi(indd) dataset('"PDS"(read member)')"
"execio * diskr indd (stem indd. finis"
"free fi(indd)"
i=1
do while i <= indd.0
if pos('text to find',indd.i) > 0 then do
"alloc shr fi(outdd) dataset('"PDS"(write member)')"
i = i + 1
push indd.i
"execio 1 diskw outdd(finis"
"free fi(outdd)"
"ispexec edit dataset('"PDS"(write member)')"
end
i = i + 1
end
end
|
|
|
Back to top |
|
|
expat
Global Moderator
Joined: 14 Mar 2007 Posts: 8797 Location: Welsh Wales
|
|
|
|
Your logic is a bit iffy
Once the required string is found you should start a new loop of reading the input stem from the point of I+1 onwards, each followed by a PUSH and EXECIO, until EOF.
At which point you should issue a LEAVE to leave the loops. |
|
Back to top |
|
|
sathyaraj
New User
Joined: 28 Sep 2007 Posts: 71 Location: India.
|
|
|
|
Guess we cant use starting line number in DISKW.. you have to use another loop as rightly said by expat |
|
Back to top |
|
|
kbrahma
New User
Joined: 08 Oct 2007 Posts: 38 Location: Delhi
|
|
|
|
Well I patched up this REXX from what I could understand from the manuals and various internet forums. I am very new to coding (let alone REXX coding)...
Just another question, is there a command which tells the loop that it has reached EOF and then leave. I could find the last written text and leave when it is found, but different files have different "last strings".
I have made several attempts to do the same (making a second loop to read the file again) and ended up with infinite looping. |
|
Back to top |
|
|
expat
Global Moderator
Joined: 14 Mar 2007 Posts: 8797 Location: Welsh Wales
|
|
|
|
As you have made an effort by yourself, I will try to help you. However, the code below is fully UNTESTED
You should take a good long read of the REXX reference manual, easily accessed from the "IBM Manuals" button at the top of the page.
Code: |
"ALLOC SHR FI(INDD) DATASET('"PDS"(READ MEMBER)')"
"EXECIO * DISKR INDD (STEM INDD. FINIS"
"FREE FI(INDD)"
DO I = 1 TO INDD.0
IF POS('TEXT TO FIND',INDD.I) > 0 THEN DO
"ALLOC SHR FI(OUTDD) DATASET('"PDS"(WRITE MEMBER)')"
DO A = I+1 TO INDD.0
PUSH INDD.A
"EXECIO 1 DISKW OUTDD"
END
"EXECIO 0 DISKW OUTDD (FINIS"
"FREE FI(OUTDD)"
"ISPEXEC EDIT DATASET('"PDS"(WRITE MEMBER)')"
LEAVE
END
END |
|
|
Back to top |
|
|
sathyaraj
New User
Joined: 28 Sep 2007 Posts: 71 Location: India.
|
|
|
|
wrote a code and found expat already has it ready
I tested this and it works fine....
Code: |
"ALLOC DA('"PDS"(WRITE)') F(WRITE) SHR"
"ALLOC DA('"PDS"(READ)') F(READ) SHR "
"EXECIO * DISKR READ (STEM INDD. FINIS"
I = 1
DO UNTIL I > = INDD.0
I = I + 1
IF POS('TEXT TO FIND',INDD.I) > 0 THEN LEAVE
END
J = 1
DO UNTIL I > INDD.0
OUTDD.J = INDD.I
J = J + 1
I = I + 1
END
"EXECIO * DISKW INPUT (STEM OUTDD. FINIS"
"FREE F(READ)"
|
|
|
Back to top |
|
|
expat
Global Moderator
Joined: 14 Mar 2007 Posts: 8797 Location: Welsh Wales
|
|
|
|
Not one to be picky .................. BUT
Code: |
I = 1
DO UNTIL I > = INDD.0
I = I + 1 |
You set I to 1, and then increment it by 1, so in effect you bypass record 1.
If record 1 contains the required information then your REXX will return incorrect results. |
|
Back to top |
|
|
Marso
REXX Moderator
Joined: 13 Mar 2006 Posts: 1353 Location: Israel
|
|
|
|
Another way for this kind of loop is to write:
Code: |
TEXTfound = 0
Do i = 1 To INrec.0
IF TEXTfound = 1 then
QUEUE INrec.i
else
IF POS('TEXT TO FIND',INrec.i) > 0 then TEXTfound = 1
End
QUEUE '' /* for end of DISKW */
"ALLOC FI(OUTPUT) DA(...) SHR"
"EXECIO * DISKW OUTPUT (FINIS" |
Note 1: a bit slower than using 2 loops. But notice how the DO takes care of the increment. And the use of the stack.
Note 2: use indentation, otherwise your program will become totally unreadable. |
|
Back to top |
|
|
sathyaraj
New User
Joined: 28 Sep 2007 Posts: 71 Location: India.
|
|
|
|
expat... you got me...
@Kbrahma
You can interchange these two lines or initialize I to 0
Code: |
IF POS('TEXT TO FIND',INDD.I) > 0 THEN LEAVE
I = I + 1
|
|
|
Back to top |
|
|
expat
Global Moderator
Joined: 14 Mar 2007 Posts: 8797 Location: Welsh Wales
|
|
|
|
Ye gods, I am so mister picky these days
I would initialise I to zero because the variable I will have an initial value of I and I+1 doesn't work too well.
Rather than
"EXECIO * DISKW OUTPUT (FINIS"
When writing queued data I have always used
"EXECIO" QUEUED() "DISKW OUTPUT (FINIS" |
|
Back to top |
|
|
kbrahma
New User
Joined: 08 Oct 2007 Posts: 38 Location: Delhi
|
|
|
|
Thanks everyone for all your help, I was not looking for the code to be put in front of me, kinda wanted to figure it out myself (with a tad bit of help).
It did occur to me that I could use stem variables for PUSH statement but just didn't know how to go about it. I tried again after posting my last message in this board and what was happening was I could get my PUSH to write different statements line to line, but everytime it read and wrote a new line, it would replace the previous line with the new one.
I know there are various manuals which can teach me which command does what in REXX, but the coding part can only come with experience (I certainly hope so, for my sake). All I can do now is to understand what logic is being used in the existing codes and try to use them in my future tasks.
Ofcourse, unless there is an easy fix which can miraculously teach me how to code, which I seriously doubt!! |
|
Back to top |
|
|
kbrahma
New User
Joined: 08 Oct 2007 Posts: 38 Location: Delhi
|
|
|
|
P.S. Oops, forgot to mention that the code is working now... Thanks again! |
|
Back to top |
|
|
|