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

REXX to extract all the lines between two particular words


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

New User


Joined: 05 May 2008
Posts: 29
Location: Chennai

PostPosted: Tue Mar 24, 2009 1:03 pm
Reply with quote

Hi All,

I have coded a REXX to extract all the lines between two particular words. The input is the COBOL program and the output should be copied to PS.

Please find the code below:

Code:
/*REXX*/
 "EXECIO * DISKR INPUT (FINIS STEM LINE."
 START="EXEC"
 EN="END-EXEC."
 J=1
 DO I=1 TO LINE.0 BY 1
 HLQ=LINE.I
 TEMP=STRIP( ''HLQ'','B')
 PARSE VAR TEMP HLQT " " APPT
 IF COMPARE(''HLQT'',''START'')=0 THEN DO
 VAL=COMPARE(''HLQT'',''EN'')
      DO WHILE VAL/=0
      IF COMPARE(''HLQT'',''EN'')=0 THEN DO
      VAL=0
      END
          NEW.J=LINE.I
         J=J+1
         I=I+1
         HLQT=LINE.I
         IF I>LINE.0 THEN DO
         VAL=0
         END
  END
   END
  END
   "EXECIO * DISKW MYOUTDD (STEM NEW. FINIS"


It extracts only first occurence of the keywords specified and displays all other lines. But I want the output such as,

EXEC
........
.......
END-EXEC.
EXEC
..........
END-EXEC.

Please help me to get the correct output.
Back to top
View user's profile Send private message
expat

Global Moderator


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

PostPosted: Tue Mar 24, 2009 1:05 pm
Reply with quote

Use TRACE I to follow through and see what happens where to find the error(s)
Back to top
View user's profile Send private message
Soundammal.S

New User


Joined: 05 May 2008
Posts: 29
Location: Chennai

PostPosted: Tue Mar 24, 2009 1:17 pm
Reply with quote

I tried with TRACE I but i didnt get any clue..Can you please help me out.
Back to top
View user's profile Send private message
dbzTHEdinosauer

Global Moderator


Joined: 20 Oct 2006
Posts: 6966
Location: porcelain throne

PostPosted: Tue Mar 24, 2009 2:28 pm
Reply with quote

why are you incrementing i ?

Quote:
I=I+1
Back to top
View user's profile Send private message
genesis786

Active User


Joined: 28 Sep 2005
Posts: 210
Location: St Katherine's Dock London

PostPosted: Tue Mar 24, 2009 3:12 pm
Reply with quote

ADD
I=I-1 after DO WHILE VAL/=0 LOOP...

Code:

DO WHILE VAL/=0                       
  IF COMPARE(''HLQT'',''EN'')=0 THEN DO
   VAL=0                               
  END                                 
  NEW.J=LINE.I                         
  SAY SPACE(NEW.J)                     
  J=J+1                               
  I=I+1                               
  HLQT=LINE.I                         
  IF I>LINE.0 THEN DO                 
    VAL=0                             
  END                                 
END                                   
I=I-1                                 
Back to top
View user's profile Send private message
genesis786

Active User


Joined: 28 Sep 2005
Posts: 210
Location: St Katherine's Dock London

PostPosted: Tue Mar 24, 2009 3:16 pm
Reply with quote

also..

you must have noted that, your logic is working fine for cases like:

EXEC
...
..
END-EXEC.
..
..
EXEC
...
...
END-EXEC.

but not when it is:

EXEC
..
..
END-EXEC.
EXEC
.. <<<--- variable 'I' pointing here after loopin in inner loop...
..
END-EXEC.

that's because your inner DO WHILE VAL/=0 loop increments I once after END-EXEC and once in our outer main loop, so it points to next line after EXEC.

hope this helps icon_smile.gif
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2546
Location: Silicon Valley

PostPosted: Tue Mar 24, 2009 8:42 pm
Reply with quote

I think it is a poor practice to increment a 'do' variable within the loop. Especially poor when there is no particular reason to do so.

I suggest using another variable name instead of 'I' here:
Code:
DO WHILE VAL/=0                       
  IF COMPARE(''HLQT'',''EN'')=0 THEN DO
   VAL=0                               
  END                                 
  NEW.J=LINE.I                         
  SAY SPACE(NEW.J)                     
  J=J+1                               
  Q=I+1                               
  HLQT=LINE.Q
  IF Q>LINE.0 THEN DO                 
    VAL=0                             
  END                                 
END                                     
Back to top
View user's profile Send private message
genesis786

Active User


Joined: 28 Sep 2005
Posts: 210
Location: St Katherine's Dock London

PostPosted: Tue Mar 24, 2009 9:03 pm
Reply with quote

another way:

Code:

DO WHILE VAL/=0                       
  IF COMPARE(''HLQT'',''EN'')=0 THEN DO
   VAL=0                               
   NEW.J=LINE.I                         
   SAY SPACE(NEW.J)                     
   J=J+1                               
   LEAVE
  END                                 
  NEW.J=LINE.I                         
  SAY SPACE(NEW.J)                     
  J=J+1                               
  I=I+1                               
  HLQT=LINE.I                         
  IF I>LINE.0 THEN DO                 
    VAL=0                             
  END                                 
END
Back to top
View user's profile Send private message
Douglas Wilder

Active User


Joined: 28 Nov 2006
Posts: 305
Location: Deerfield IL

PostPosted: Wed Mar 25, 2009 3:26 am
Reply with quote

You have a very nice loop here
Code:
DO I=1 TO LINE.0 BY 1

Why do you need another loop?
Code:
DO WHILE VAL/=0


Just use the first loop, check to see if you need to print the line you are on and if so put it in the output stem.
Back to top
View user's profile Send private message
MBabu

Active User


Joined: 03 Aug 2008
Posts: 400
Location: Mumbai

PostPosted: Wed Mar 25, 2009 9:24 am
Reply with quote

I haven't traced the logic of this but I've never seen COMPARE(). Why not just compare the strings? Also, no need to concatenate empty strings ('') to the variables.
IF COMPARE(''HLQT'',''START'')=0 THEN
would be more efficient as
IF HLQT = START THEN

Also, this code does not appear to take into account the fact that the words can also appear in comments, be lower case, be on the same line eg: EXEC CICS RETURN END-EXEC, have sequence numbers in 1-6 or 73-80 or that the statement can end with a period. This code might work better
Code:
/* REXX  */
"EXECIO * DISKR INPUT (FINIS STEM LINE."
EXECSTMT = 0
TAIL=0
DO I = 1 TO LINE.0
  PARSE UPPER VAR LINE.I . 7 LINE 73 .
  LINE = TRANSLATE(LINE," ",".")
  IF SUBSTR(LINE,1,1) = "*" THEN ITERATE
  PARSE VAR LINE KEYWORD .
  IF KEYWORD = "EXEC" & \EXECSTMT THEN EXECSTMT = 1
  IF EXECSTMT THEN
    DO
     TAIL=TAIL+1
     NEW.TAIL=LINE.I
    END
  IF WORDPOS("END-EXEC",LINE)>0 THEN EXECSTMT = 0
END
NEW.0=TAIL
"EXECIO * DISKW MYOUTDD (STEM NEW. FINIS"
Back to top
View user's profile Send private message
Soundammal.S

New User


Joined: 05 May 2008
Posts: 29
Location: Chennai

PostPosted: Wed Mar 25, 2009 12:28 pm
Reply with quote

Thanks Babu. It is working fine.
Back to top
View user's profile Send private message
Soundammal.S

New User


Joined: 05 May 2008
Posts: 29
Location: Chennai

PostPosted: Wed Mar 25, 2009 1:22 pm
Reply with quote

Hi All,

Now I'm able to extract the lines between EXEC and END-EXEC. My output is like this,

026300 EXEC SQL
026400 INCLUDE SQLCA
026500 END-EXEC.

Can I remove the line numbers using STRIP command? Please suggest.
Back to top
View user's profile Send private message
genesis786

Active User


Joined: 28 Sep 2005
Posts: 210
Location: St Katherine's Dock London

PostPosted: Wed Mar 25, 2009 2:39 pm
Reply with quote

TRY..

Code:

STRIP(TRANSLATE(WORD(LINE.I,1),' ','1234567890'),,' ')
Back to top
View user's profile Send private message
MBabu

Active User


Joined: 03 Aug 2008
Posts: 400
Location: Mumbai

PostPosted: Wed Mar 25, 2009 8:20 pm
Reply with quote

Soundammal.S wrote:
Can I remove the line numbers using STRIP command? Please suggest.

Yes, but that will shift over lines that have sequence numbers and not those that don't. my sample rexx was written so that you could print either the original line including sequence numbers or the line with no sequence numbers. just print LINE instead of LINE.I on line 14. Actually, you should create a new variable with parse as is done in line 6 since LINE will be upper case and have its periods removed, but you get the idea.
Back to top
View user's profile Send private message
Soundammal.S

New User


Joined: 05 May 2008
Posts: 29
Location: Chennai

PostPosted: Wed Mar 25, 2009 8:22 pm
Reply with quote

Hi All,

The below code is working fine.

/* REXX */
"ALLOC F(INPUT) DA('MYHLQ.INPUTFIL') SHR "
"EXECIO * DISKR INPUT (FINIS STEM LINE."
"FREE F(INPUT)"
EXECSTMT = 0
TAIL=0
DO I = 1 TO LINE.0
PARSE UPPER VAR LINE.I . 10 LINE 73 .
LINE = TRANSLATE(LINE," ",".")
IF SUBSTR(LINE,1,1) = "*" THEN ITERATE
PARSE VAR LINE KEYWORD .
IF KEYWORD = "EXEC" & \EXECSTMT THEN EXECSTMT = 1
IF EXECSTMT THEN
DO
TAIL=TAIL+1
K=LINE.I
PARSE VAR K VAR1 " " VAR2
NEW.TAIL=VAR2
END
IF WORDPOS("END-EXEC",LINE)>0 THEN EXECSTMT = 0
END
NEW.0=TAIL
"DELETE 'T49NXSS.TEST'"
"ALLOC DA('MYHLQ.TEST') F(MYOUTDD) NEW REUSE"
"EXECIO * DISKW MYOUTDD (OPEN"
"EXECIO * DISKW MYOUTDD (STEM NEW. "
"EXECIO * DISKW MYOUTDD (FINIS"
"FREE F(MYOUTDD)"


Thank you all for your support.
Back to top
View user's profile Send private message
Mickeydusaor

Active User


Joined: 24 May 2006
Posts: 258
Location: Salem, Oregon

PostPosted: Wed Mar 25, 2009 9:07 pm
Reply with quote

you do not need to have 3 EXECIO commands, 1 would do the same thing as the 3.

"EXECIO * DISKW MYOUTDD (STEM NEW. FINIS"
Back to top
View user's profile Send private message
MBabu

Active User


Joined: 03 Aug 2008
Posts: 400
Location: Mumbai

PostPosted: Thu Mar 26, 2009 12:56 am
Reply with quote

Also, I'm not sure what PARSE VAR K VAR1 " " VAR2 is supposed to do, though I assume it is supposed to remove the 1st word. The space is implied so having a quoted blank doesn't do anything and I'm not sure why you would want to remove the 1st word of each line. Also there is no need to assign var1 if you aren't going to use it so a period is more efficient, eg: parse var K . var2
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 Running REXX through JOB CLIST & REXX 13
No new posts Error to read log with rexx CLIST & REXX 11
No new posts isfline didnt work in rexx at z/OS ve... CLIST & REXX 7
No new posts run rexx code with jcl CLIST & REXX 15
No new posts Execute secondary panel of sdsf with ... CLIST & REXX 1
Search our Forums:

Back to Top