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.