Hi ,
I am running this code but the output result I am getting in SAS log. I want these output in a sas dataset.
Any solution will be appreciate.
%macro list_files(dir,ext);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));
%if &did eq 0 %then %do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;
%do i = 1 %to %sysfunc(dnum(&did));
%let name=%qsysfunc(dread(&did,&i));
%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
%put &dir/&name;
%end;
%else %if %qscan(&name,2,.) = %then %do;
%list_files(&dir/&name,&ext)
%end;
%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));
%mend list_files;
%list_files(/sasdata/im_pic_sas,sas)
Instead of %PUTting things to the log, create statements (because creating code is what the macro processor is meant to do):
%macro list_files(dir,ext);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));
%if &did eq 0 %then %do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;
%do i = 1 %to %sysfunc(dnum(&did));
%let name=%qsysfunc(dread(&did,&i));
%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
fname = "&dir/&name";
output;
%end;
%else %if %qscan(&name,2,.) = %then %do;
%list_files(&dir/&name,&ext)
%end;
%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));
%mend list_files;
and then use the macro in the proper place:
data myfiles;
length fname $200;
%list_files(your_path,sas)
run;
The %PUT statement writes to the LOG. If you don't want this, then you need to re-write the macro so that the results go to a SAS data set. In fact, if you search these forums, you will find many examples of the code that will write this information to the SAS data set.
Also, see Maxim 23.
Instead of %PUTting things to the log, create statements (because creating code is what the macro processor is meant to do):
%macro list_files(dir,ext);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));
%if &did eq 0 %then %do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;
%do i = 1 %to %sysfunc(dnum(&did));
%let name=%qsysfunc(dread(&did,&i));
%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
fname = "&dir/&name";
output;
%end;
%else %if %qscan(&name,2,.) = %then %do;
%list_files(&dir/&name,&ext)
%end;
%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));
%mend list_files;
and then use the macro in the proper place:
data myfiles;
length fname $200;
%list_files(your_path,sas)
run;
Thank You Sir! This is working.
Appreciate your help!
Another option is to add functionality to the macro so that you have the option of either writing to the log or creating an output dataset.
Within the macro, it would need to generate the full code for a DATA step. With a recursive macro like this, it takes a bit more thinking. Because on the first iteration only, you want it to start writing the DATA step. Then on every iteration it outputs a record. And at the end of the first iteration it ends the DATA step.
Something like:
%macro list_files(dir,ext,out=);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));
%*If out= was specified, and not one of the recursive calls, start writing a data step ;
%if %superq(out) ne %str() and %sysmexecname(%sysmexecdepth - 1) ne LIST_FILES
%then %do;
data &out ;
length path $200 ; *Pick a longer length if you have longer paths ;
%end;
%if &did eq 0 %then %do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;
%do i = 1 %to %sysfunc(dnum(&did));
%let name=%qsysfunc(dread(&did,&i));
%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
%put &dir/&name;
%*Write the path to output dataset ;
%if %superq(out) ne %str() %then %do ;
path="&dir/&name" ;
output ;
%end ;
%end;
%else %if %qscan(&name,2,.) = %then %do;
%list_files(&dir/&name,&ext)
%end;
%end;
%*If out= was specified, and not one of the recursive calls, end the data step ;
%if %superq(out) ne %str() and %sysmexecname(%sysmexecdepth - 1) ne LIST_FILES
%then %do;
run ;
%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));
%mend list_files;
options mprint ;
%list_files(/sasdata/im_pic_sas, sas, out=work.want)
Available on demand!
Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.
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.