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
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.