Skip to content
Advertisement

Apparent invocation of macro not resolved in sas filename pipe

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.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement