Here is a new twist on an old trope. Recursive find files will create a data set listing all files below a root path to a certain depth. Recursion in DATA Step made possible by maintaining state data (i.e. stack) in a hash object. The only downside is that sub-folder detection in SAS is done via MOPEN returning a 0, which means every file detected has an attempted open and it takes a lot longer to get the results than say a bash find command.
Sample code:
%let root = G:;
%let maxdepth = 2;
data find_files (keep=folder filename);
length folder $2000 fref $8 filename $2000 index dnum 8 ;
call missing (depth, did, folder, index, dnum);
declare hash state ();
state.defineKey ('depth');
state.defineData ('fref', 'did', 'folder', 'index', 'dnum');
state.defineDone();
folder = "&root";
depth = 0;
maxdepth = &maxdepth;
link push;
goto iterate;
push:
depth = depth + 1;
link fref;
did = dopen (fref);
if did = 0 then stop;
filename = '';
output;
dnum = dnum (did);
index = 0;
state.add();
if depth > maxdepth then do;
link pop;
goto iterate;
end;
return;
%*-------------------------------------------------------;
iterate:
%*-------------------------------------------------------;
if index >= dnum then do;
link pop;
goto iterate;
end;
index + 1;
state.replace();
filename = dread(did, index);
mid = mopen(did, filename);
if mid = 0 then do;
folder = catx ('/', folder, filename);
link push;
goto iterate;
end;
* add FINFO() calls here to obtain file size and mod date;
mid = fclose(mid);
output;
goto iterate;
%*-------------------------------------------------------;
pop:
%*-------------------------------------------------------;
did = dclose(did);
rc = filename (fref);
state.remove();
depth = depth - 1;
if depth = 0 then stop;
state.find();
return;
%*-------------------------------------------------------;
fref:
%*-------------------------------------------------------;
call missing (fref);
rc = filename (fref, folder);
if rc ne 0 then do;
msg = sysmsg();
put msg;
stop;
end;
return;
run;
If your subtree is too large to load into a hash object you can use the MODIFY statement to affect a recursive search.
https://github.com/sasutils/macros/blob/master/dirtree.sas
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
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.