Hi,
I would like to replace a generic part of a string and replace with value from one variable in another variable.
/*input*/
DATA input;
LENGTH LIB_TABLES $100;
INPUT LIB_TABLES;
DATALINES;
LIB_A.TABLE_1
LIB_B.TABLE_2
LIB_C.TABLE_3
;
RUN;
/*What I have*/
DATA have;
SET input;
LIB = SCAN( LIB_TABLES, 1, '.');
TABLES = REVERSE(SCAN(REVERSE(LIB_TABLES),1,'.'));
X_have= 'info_tables(LIBNAME=XXX, TABLE=XXX, Table info)';
RUN;
/*Desirable output*/
DATA want;
LIB_TABLES = 'LIB_A.TABLE_1';
LIB = 'LIB_A';
TABLES = 'TABLE_1';
X_WANT = 'info_tables(LIBNAME=LIB_A,TABLE=TABLE_1, Table info)';
OUTPUT;
LIB_TABLES = 'LIB_B.TABLE_2';
LIB = 'LIB_B';
TABLES = 'TABLE_2';
X_WANT = 'info_tables(LIBNAME=LIB_B,TABLE=TABLE_2, Table info)';
OUTPUT;
LIB_TABLES = 'LIB_C.TABLE_3';
LIB = 'LIB_C';
TABLES = 'TABLE_3';
X_WANT = 'info_tables(LIBNAME=LIB_C,TABLE=TABLE_3, Table info)';
OUTPUT;
RUN;
How should I do it?
Many thanks,
As you stated that you wanted to _replace_ a certain char group by a variable my suggestion would be using the tranwrd function . ... note the trim(). This was suggested by @Tom in this post
/*input*/
DATA input;
LENGTH LIB_TABLES $100;
INPUT LIB_TABLES;
DATALINES;
LIB_A.TABLE_1
LIB_B.TABLE_2
LIB_C.TABLE_3
;
RUN;
/*What I have*/
DATA have;
SET input;
LIB = SCAN( LIB_TABLES, 1, '.');
TABLES = REVERSE(SCAN(REVERSE(LIB_TABLES),1,'.'));
X_have= 'info_tables(LIBNAME=XXX, TABLE=YYY, Table info)';
x_want=tranwrd(tranwrd(x_have, "YYY", trim(TABLES)), "XXX", trim(LIB));
RUN;
proc print data=have;
Hi:
You are very close. Using one of the concatenate functions to join your text and your variable values will work. I'd recommend the CATT function, which trims blanks:
I also simplified your SCAN, since using a -1 tells SCAN to start scanning from the other end of the variable string, which is what your REVERSES were doing.
Cynthia
As you stated that you wanted to _replace_ a certain char group by a variable my suggestion would be using the tranwrd function . ... note the trim(). This was suggested by @Tom in this post
/*input*/
DATA input;
LENGTH LIB_TABLES $100;
INPUT LIB_TABLES;
DATALINES;
LIB_A.TABLE_1
LIB_B.TABLE_2
LIB_C.TABLE_3
;
RUN;
/*What I have*/
DATA have;
SET input;
LIB = SCAN( LIB_TABLES, 1, '.');
TABLES = REVERSE(SCAN(REVERSE(LIB_TABLES),1,'.'));
X_have= 'info_tables(LIBNAME=XXX, TABLE=YYY, Table info)';
x_want=tranwrd(tranwrd(x_have, "YYY", trim(TABLES)), "XXX", trim(LIB));
RUN;
proc print data=have;
Thank you for the double-trim. Will come in handy for replacing in a string 😁
Hi,
I got so many good solutions from the community. Thank you for helping me. This one works as charm! 🙏
To re-create your example does NOT require replacing any text.
Just GENERATE the text.
DATA input;
LENGTH LIB_TABLES $100;
INPUT LIB_TABLES;
DATALINES;
LIB_A.TABLE_1
LIB_B.TABLE_2
LIB_C.TABLE_3
;
data want;
set input;
length lib $8 tables $32 x_want $100 ;
lib=scan(lib_tables,1,'.');
tables=scan(lib_tables,-1,'.');
x_want=cats('info_tables(libname=',lib,',table=',tables,',Table info)');
run;
Result
Obs LIB_TABLES lib tables x_want 1 LIB_A.TABLE_1 LIB_A TABLE_1 info_tables(libname=LIB_A,table=TABLE_1,Table info) 2 LIB_B.TABLE_2 LIB_B TABLE_2 info_tables(libname=LIB_B,table=TABLE_2,Table info) 3 LIB_C.TABLE_3 LIB_C TABLE_3 info_tables(libname=LIB_C,table=TABLE_3,Table info)
Do you have an example where you actually need to replace text?
Thank you for helping me. Another good solution. 😊
Regarding your question, Do you have an example where you actually need to replace text? and the reason I need help with this because I was looking for a solution for a makro where I use lib and tables and I wanted to avoid to copy/pase the XXX.
It can be time consuming when it's 20 tables.
Pretty much the same as Tom already suggested with the one extension to also deal with one level table names.
DATA have;
LENGTH LIB_TABLES $100;
INPUT LIB_TABLES;
DATALINES;
LIB_A.TABLE_1
LIB_B.TABLE_2
LIB_C.TABLE_3
TABLE4
;
data want;
set have;
length lib $8 tables $32 x_want $100;
lib=scan(cats('WORK.',lib_tables),-2,'.');
tables=scan(lib_tables,-1,'.');
x_want=cats('info_tables(LIBNAME=',lib,', table=',tables,', Table info)');
run;
Hi,
Thanks for expanding the solution, having WORK as default. Real nice 👏
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.