I am using the following SAS code to find all files and their sizes under the directory &directory.
filename tmp pipe "find &directory. -type f -printf '%p %sn'";
data all_files;
infile tmp;
length file_path $255. size 8.;
input file_path size;
run;
Though the output data tmp
is what I want, the code will give me warning.
WARNING: Apparent invocation of macro S not resolved.
I have tried adding an extra ‘%’ before ‘%’, i.e.
filename tmp pipe "find &directory. -type f -printf '%%p %%sn'"
but it doesn’t work.
How can I get rid of the warning? Thank you.
I have also tried %str
and %nrstr
,
filename tmp pipe %str("find &directory. -type f -printf '%p %sn'");
filename tmp pipe %nrstr("find &directory. -type f -printf '%p %sn'");
filename tmp pipe %str("find &directory. -type f -printf '%%p %%sn'");
filename tmp pipe %nrstr("find &directory. -type f -printf '%%p %%sn'");
filename tmp pipe "find &directory. -type f -printf '%str(%%)p %str(%%)sn'");
filename tmp pipe "find &directory. -type f -printf '%nrstr(%%)p %nrstr(%%)sn'");
None of them solved the problem.
Advertisement
Answer
The macro processor will look for macro triggers &
and %
inside of strings enclosed in double quotes, but not those enclosed in single quotes. You can use the quote()
function to enclose the string in single quotes.
%let cmd=find &directory/ -type f -printf '%s %pn' ;
filename tmp pipe %sysfunc(quote(&cmd,%str(%')));
Or you can just use SAS code and avoid letting the macro processor get involved.
Instead of making a FILENAME statement you could use a datastep to call the FILENAME()
function.
data _null_;
rc=filename('TMP'
,catx(' ',"find &directory/ -type f -printf",quote('%s %pn',"'"))
,'PIPE');
put rc= ;
run;
data all_files;
infile tmp truncover;
input size file_path $255. ;
run;
Or you could not create a fileref at all and instead just use the FILEVAR=
option on the INFILE
statement to pass in the command.
data all_files;
length cmd $200;
cmd = catx(' ',"find &directory/ -type f -printf",quote('%s %pn',"'"));
infile tmp pipe filevar=cmd truncover;
input size file_path $255. ;
run;
Note: reversing the order of the size and path in the printf string will avoid issues parsing the results when there are filenames that have embedded spaces.