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

How to replace a string dynamically in Rexx


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

New User


Joined: 04 Mar 2021
Posts: 6
Location: India

PostPosted: Thu Mar 04, 2021 3:17 pm
Reply with quote

Hi,

I am trying to create a new job, based on the sample job keyed-in by user in a REXX panel. Please note that user also provides few other details to be updated in the new job.
I had used POS,OVERLAY functions to override/replace the string/values that user provided in the rexx panel.

when the search string length is more than the string to be replaced, the result is not as expected.
To give you an example about the problem:
Sample job code:
//JS0010 EXEC PROC1,
// HLQ1='SYS1',
// HLQ2='SYSPN',
// DMPUBLIB='SYS1.COD.ORANGE.PROCESS',
// CNTL='AAAA.BBBB.CCC.PR.CNTL',
// MEM1='CNTL1',
// MEM2='CNTL2'

//*

Expected,in New job:
//JS0010 EXEC PROC1,
// HLQ1='SYS1',
// HLQ2='SYSPN',
// DMPUBLIB='SYS1.COD.ORANGE.PROCESS',
// CNTL='AAAA.BBBB.CCC.PR.CNTL',
// MEM1='NEW1',
// MEM2='NEW2'

//*


Output with my code:
//JS0010 EXEC PROC1,
// HLQ1='SYS1',
// HLQ2='SYSPN',
// DMPUBLIB='SYS1.COD.ORANGE.PROCESS',
// CNTL='AAAA.BBBB.CCC.PR.CNTL',
// MEM1='NEW11',
// MEM2='NEW22'

//*

I read sample job to a stem var. The search string and the replace strings both are in rexx program variables.

Any suggestions would be of great help. Thank you.
Back to top
View user's profile Send private message
Joerg.Findeisen

Senior Member


Joined: 15 Aug 2015
Posts: 1231
Location: Bamberg, Germany

PostPosted: Thu Mar 04, 2021 3:31 pm
Reply with quote

Use code tags when presenting Code/Data to make it more readable for others. Provide the REXX that produces your unexpected output.
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10872
Location: italy

PostPosted: Thu Mar 04, 2021 4:04 pm
Reply with quote

read the rexx manual pages that describe the overlay function
Back to top
View user's profile Send private message
hsrPulivarthi19

New User


Joined: 04 Mar 2021
Posts: 6
Location: India

PostPosted: Thu Mar 04, 2021 5:16 pm
Reply with quote

Here is my rexx code:

GEN_NEW_JOB:
/*-----------*/

DO I=1 TO Njob.0
say 'before:' NJOB.I

posvar = 0 ; posvar= POS(Sjob,Njob.i)
IF POSvar > 0 then
njob.i = OVERLAY(JobNm,Njob.i,posvar)

posvar = 0 ; posvar= POS(SCMEM2,Njob.i)
IF POSvar > 0 then
njob.i = OVERLAY(NCMEM2,Njob.i,posvar)

posvar = 0 ; posvar= POS(SCMEM1,Njob.i)
IF POSvar > 0 then
njob.i = OVERLAY(NCMEM1,Njob.i,posvar)

say 'After: ' NJOB.I
END

Output:
before: // MEM1='GF010X',
After: // MEM1='CN110X',

before: // MEM2='GF010XC'
After: // MEM2='CN210XC'

Expected o/p:
before: // MEM1='GF010X',
After: // MEM1='CN1',

before: // MEM2='GF010XC'
After: // MEM2='CN2'
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10872
Location: italy

PostPosted: Thu Mar 04, 2021 5:34 pm
Reply with quote

you might be
Quote:
A Quick Learner

but you must achieve netter reading skills

Your code does not work because You did not care to try to understand how overlay works

try this

Code:
in = "// MEM1='OLD',"

chgs = "l2 l03 l004 l0005"

parse var in head "='" body "'" tail

say "head" head
say "body" body
say "tail" tail

say "old >>>"in"<<<"
say
do i = 1 to words(chgs)
  say "new >>>" || head || "='" || word(chgs,i) || "'" || tail || "<<<"
end


to get ...
Code:
old >>>// MEM1='OLD',<<<

new >>>// MEM1='l2',<<<
new >>>// MEM1='l03',<<<
new >>>// MEM1='l004',<<<
new >>>// MEM1='l0005',<<<
Back to top
View user's profile Send private message
don.leahy

Active Member


Joined: 06 Jul 2010
Posts: 765
Location: Whitby, ON, Canada

PostPosted: Thu Mar 04, 2021 6:39 pm
Reply with quote

Have you considered using ISPF File Tailoring? It is specifically designed to merge user input from a panel with JCL in a skeleton.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2012
Location: USA

PostPosted: Thu Mar 04, 2021 7:00 pm
Reply with quote

My approach is always: use a simple tools to do a simple job.

When I need to hammer a nail, I use just a hammer, but do not try to develop any GPS-controlled robotic device with artificial intelligence.

For this extremely trivial task I suggest to use one of standard utilities, like SORT (also FileAid, and others are suitable)

Code:
 SORT FIELDS=COPY
 OUTFIL FINDREP=(INOUT=(C’GF010X’,C’CN1’,
                        C’GF010XC’,C’CN2’))
 END

That’s it...
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2012
Location: USA

PostPosted: Thu Mar 04, 2021 7:11 pm
Reply with quote

If “REXX is strictly required by management” then another simple solution would be:
Code:
Do i = 1 to OldWords.0
   If 0 < Pos( OldWords.i, TextLine ) Then Do
      Parse Var TextLine PreText (OldWords.i) PostText
      TextLine = PreText || NewWords.i || PostText
   End
End i


That’s it, again...
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2012
Location: USA

PostPosted: Thu Mar 04, 2021 7:25 pm
Reply with quote

When working with real “words” (no spaces in between) in REXX there is even better solution, to avoid bad looking “stems”.
Code:
OldWords = ‘CF010X CF010XC’
NewWords = ‘CN1 CN2’

Do i = 1 To Words(OldWords)
   CheckWord = SubWord( OldWords, i )
   If 0 < Pos( CheckWord, TextLine ) Then Do
      Parse Var TextLine PreText (CheckWord) PostText
      TextLine = PreText || SubWord( NewWords, i ) || PostText
   End
End i
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2012
Location: USA

PostPosted: Thu Mar 04, 2021 7:34 pm
Reply with quote

When using any way of implementation, you MUST pay attention to: verify longer words before shorter ones, or not!

In your own example the word ‘CF010X’ will be replaced instead of ‘CF010XC’...

In my implementation examples I just followed your method of verification, it may be either correct, or wrong - depending on your actual requirements.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2012
Location: USA

PostPosted: Thu Mar 04, 2021 10:11 pm
Reply with quote

sergeyken wrote:
When working with real “words” (no spaces in between) in REXX there is even better solution, to avoid bad looking “stems”.
Code:
OldWords = ‘CF010X CF010XC’
NewWords = ‘CN1 CN2’

Do i = 1 To Words(OldWords)
   CheckWord = SubWord( OldWords, i )
   If 0 < Pos( CheckWord, TextLine ) Then Do
      Parse Var TextLine PreText (CheckWord) PostText
      TextLine = PreText || SubWord( NewWords, i ) || PostText
   End
End i

P.S.
In my example, both functions SubWord do require the third optional parameter; the default value is not 1:
Code:
CheckWord = SubWord( OldWords, i, 1 )
. . . . . etc. . . . . . .

Also more simple function Word() can be used
Code:
CheckWord = Word( OldWords, i )
. . . . . . . Etc. . . . . . . .
Back to top
View user's profile Send private message
hsrPulivarthi19

New User


Joined: 04 Mar 2021
Posts: 6
Location: India

PostPosted: Fri Mar 05, 2021 7:32 am
Reply with quote

enrico-sorichetti wrote:
you might be
Quote:
A Quick Learner

but you must achieve netter reading skills

Your code does not work because You did not care to try to understand how overlay works

try this

Code:
in = "// MEM1='OLD',"

chgs = "l2 l03 l004 l0005"

parse var in head "='" body "'" tail

say "head" head
say "body" body
say "tail" tail

say "old >>>"in"<<<"
say
do i = 1 to words(chgs)
  say "new >>>" || head || "='" || word(chgs,i) || "'" || tail || "<<<"
end


to get ...
Code:
old >>>// MEM1='OLD',<<<

new >>>// MEM1='l2',<<<
new >>>// MEM1='l03',<<<
new >>>// MEM1='l004',<<<
new >>>// MEM1='l0005',<<<




Thank you for your solution & suggestion.
Regarding the solution,
My search string do not start/preceded always with a specific char (like '=', ',' etc).
After referring multiple suggestions from the forum, I am able to achieve the desired results with parse function.

Below is the customized solution.

PRETEXT=' ' ; POSTTEXT=' ';
if pos(srchstr,srcline) > 0 then
do
PARSE VAR srcline PRETEXT (srchstr) POSTTEXT
srcline = PRETEXT||replstr||POSTTEXT
end
Back to top
View user's profile Send private message
hsrPulivarthi19

New User


Joined: 04 Mar 2021
Posts: 6
Location: India

PostPosted: Fri Mar 05, 2021 7:43 am
Reply with quote

sergeyken wrote:
sergeyken wrote:
When working with real “words” (no spaces in between) in REXX there is even better solution, to avoid bad looking “stems”.
Code:
OldWords = ‘CF010X CF010XC’
NewWords = ‘CN1 CN2’

Do i = 1 To Words(OldWords)
   CheckWord = SubWord( OldWords, i )
   If 0 < Pos( CheckWord, TextLine ) Then Do
      Parse Var TextLine PreText (CheckWord) PostText
      TextLine = PreText || SubWord( NewWords, i ) || PostText
   End
End i

P.S.
In my example, both functions SubWord do require the third optional parameter; the default value is not 1:
Code:
CheckWord = SubWord( OldWords, i, 1 )
. . . . . etc. . . . . . .

Also more simple function Word() can be used
Code:
CheckWord = Word( OldWords, i )
. . . . . . . Etc. . . . . . . .


Hi,
Thankyou for your suggestions.

Your code helped me to customize solution as per my requirement. This is the final code, which is giving my desired output.

PRETEXT=' ' ; POSTTEXT=' ';
if pos(srchstr,srcline) > 0 then
do
PARSE VAR srcline PRETEXT (srchstr) POSTTEXT
srcline = PRETEXT||replstr||POSTTEXT
end

Output:
before: //PN2G010X JOB CZXXX002,'YYYYYY',CLASS=J,REGION=0M,TIME=1440,
After: //GN2G010X JOB CZXXX002,'YYYYYY',CLASS=J,REGION=0M,TIME=1440,

before: // MEM1='GF010X',
After: // MEM1='CN1',

before: // MEM2='GF010XC'
After: // MEM2='CONTROL2'

I have tried parse like this earlier, which did not give the desired results. (Syntax differs.)

PRETEXT=' ' ; POSTTEXT=' ';
if pos(srchstr,srcline) > 0 then
do
PARSE VAR srcline PRETEXT srchstr POSTTEXT
srcline = PRETEXT||replstr||POSTTEXT
end


which gave below output:
before: //PN2G010X JOB CZXXX002,'YYYYYY',CLASS=J,REGION=0M,TIME=1440,
After: //PN2G010XGN2G010XCZXXX002,'YYYYYY',CLASS=J,REGION=0M,TIME=1440,
Back to top
View user's profile Send private message
hsrPulivarthi19

New User


Joined: 04 Mar 2021
Posts: 6
Location: India

PostPosted: Fri Mar 05, 2021 11:24 am
Reply with quote

don.leahy wrote:
Have you considered using ISPF File Tailoring? It is specifically designed to merge user input from a panel with JCL in a skeleton.


Hi,

Yes, I am aware of File tailoring services. To use tailored services a fixed template/skeleton is required, which we wanted to avoid for our requirement.
Back to top
View user's profile Send private message
hsrPulivarthi19

New User


Joined: 04 Mar 2021
Posts: 6
Location: India

PostPosted: Fri Mar 05, 2021 11:28 am
Reply with quote

sergeyken wrote:
When using any way of implementation, you MUST pay attention to: verify longer words before shorter ones, or not!

In your own example the word ‘CF010X’ will be replaced instead of ‘CF010XC’...

In my implementation examples I just followed your method of verification, it may be either correct, or wrong - depending on your actual requirements.


What you said is true.
To resolve this, I had longer words check prior to the shorter words.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2012
Location: USA

PostPosted: Fri Mar 05, 2021 6:57 pm
Reply with quote

Please, Learn how to use code tags in your messages!
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2012
Location: USA

PostPosted: Fri Mar 05, 2021 7:03 pm
Reply with quote

I highly recommend to eliminate all unneeded operations from any of your code. For instance, all useless initialization of variables, like those ones:

posvar = 0
PRETEXT = ‘’
POSTTEXT = ‘’

All of those variables are assigned correct required values by just the next statements; in this manner you may get 30%-50% of your code filled with this unneeded garbage. This is as senseless as
Code:
z = 0
z = x + y
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 Replace each space in cobol string wi... COBOL Programming 2
No new posts PARSE Syntax for not fix length word ... JCL & VSAM 7
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
Search our Forums:

Back to Top