IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Writing multiple lines in a PDS member?


IBM Mainframe Forums -> CLIST & REXX
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
kbrahma

New User


Joined: 08 Oct 2007
Posts: 38
Location: Delhi

PostPosted: Fri Nov 13, 2009 6:20 pm
Reply with quote

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
View user's profile Send private message
expat

Global Moderator


Joined: 14 Mar 2007
Posts: 8797
Location: Welsh Wales

PostPosted: Fri Nov 13, 2009 6:39 pm
Reply with quote

Your logic is a bit iffy icon_sad.gif

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
View user's profile Send private message
sathyaraj

New User


Joined: 28 Sep 2007
Posts: 71
Location: India.

PostPosted: Fri Nov 13, 2009 6:45 pm
Reply with quote

Guess we cant use starting line number in DISKW.. you have to use another loop as rightly said by expat
Back to top
View user's profile Send private message
kbrahma

New User


Joined: 08 Oct 2007
Posts: 38
Location: Delhi

PostPosted: Fri Nov 13, 2009 7:01 pm
Reply with quote

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
View user's profile Send private message
expat

Global Moderator


Joined: 14 Mar 2007
Posts: 8797
Location: Welsh Wales

PostPosted: Fri Nov 13, 2009 7:15 pm
Reply with quote

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
View user's profile Send private message
sathyaraj

New User


Joined: 28 Sep 2007
Posts: 71
Location: India.

PostPosted: Fri Nov 13, 2009 7:35 pm
Reply with quote

wrote a code and found expat already has it ready icon_smile.gif

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
View user's profile Send private message
expat

Global Moderator


Joined: 14 Mar 2007
Posts: 8797
Location: Welsh Wales

PostPosted: Sat Nov 14, 2009 1:48 am
Reply with quote

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
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Sat Nov 14, 2009 4:56 am
Reply with quote

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
View user's profile Send private message
sathyaraj

New User


Joined: 28 Sep 2007
Posts: 71
Location: India.

PostPosted: Sat Nov 14, 2009 6:37 am
Reply with quote

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
View user's profile Send private message
expat

Global Moderator


Joined: 14 Mar 2007
Posts: 8797
Location: Welsh Wales

PostPosted: Sat Nov 14, 2009 3:59 pm
Reply with quote

Ye gods, I am so mister picky these days icon_biggrin.gif

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
View user's profile Send private message
kbrahma

New User


Joined: 08 Oct 2007
Posts: 38
Location: Delhi

PostPosted: Mon Nov 16, 2009 1:22 pm
Reply with quote

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. icon_sad.gif

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!! icon_lol.gif
Back to top
View user's profile Send private message
kbrahma

New User


Joined: 08 Oct 2007
Posts: 38
Location: Delhi

PostPosted: Mon Nov 16, 2009 1:33 pm
Reply with quote

P.S. Oops, forgot to mention that the code is working now... Thanks again!
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> CLIST & REXX

 


Similar Topics
Topic Forum Replies
No new posts INCLUDE OMIT COND for Multiple values... DFSORT/ICETOOL 5
No new posts Replace Multiple Field values to Othe... DFSORT/ICETOOL 12
No new posts Multiple table unload using INZUTILB DB2 2
No new posts Grouping by multiple headers DFSORT/ICETOOL 7
No new posts How to append a PS file into multiple... JCL & VSAM 3
Search our Forums:

Back to Top