SAS的文件名管道中未解析宏的表观调用

时间:2019-01-24 02:40:47

标签: linux sas pipe sas-macro

我正在使用以下SAS代码在目录&directory.下查找所有文件及其大小

filename tmp pipe "find &directory. -type f -printf '%p %s\n'";
data all_files;
  infile tmp;
  length file_path $255. size 8.;
  input file_path size;
run;

尽管输出数据tmp是我想要的,但是代码会给我警告。

  

警告:宏S的表观调用未解决。

我尝试在“%”之前添加一个额外的“%”,即

filename tmp pipe "find &directory. -type f -printf '%%p %%s\n'"

但它不起作用。

如何摆脱警告?谢谢。


我也尝试过%str%nrstr

filename tmp pipe %str("find &directory. -type f -printf '%p %s\n'");
filename tmp pipe %nrstr("find &directory. -type f -printf '%p %s\n'");
filename tmp pipe %str("find &directory. -type f -printf '%%p %%s\n'");
filename tmp pipe %nrstr("find &directory. -type f -printf '%%p %%s\n'");
filename tmp pipe "find &directory. -type f -printf '%str(%%)p %str(%%)s\n'");
filename tmp pipe "find &directory. -type f -printf '%nrstr(%%)p %nrstr(%%)s\n'");

他们都没有解决问题。

2 个答案:

答案 0 :(得分:2)

宏处理器将在用双引号引起来的字符串中查找宏触发器&%,而不是用单引号引起来的宏触发器。您可以使用quote()函数将字符串用单引号引起来。

%let cmd=find &directory/ -type f -printf '%s %p\n' ;
filename tmp pipe %sysfunc(quote(&cmd,%str(%')));

或者您可以只使用SAS代码,避免让宏处理器参与其中。

您可以使用数据步骤来调用FILENAME()函数,而不是执行FILENAME语句。

data _null_;
  rc=filename('TMP'
     ,catx(' ',"find &directory/ -type f -printf",quote('%s %p\n',"'"))
     ,'PIPE');
  put rc= ;
run;
data all_files;
  infile tmp truncover;
  input size file_path $255. ;
run;

或者您根本无法创建fileref,而只是使用FILEVAR=语句上的INFILE选项来传递命令。

data all_files;
  length cmd $200;
  cmd = catx(' ',"find &directory/ -type f -printf",quote('%s %p\n',"'"));
  infile tmp pipe filevar=cmd truncover;
  input size file_path $255. ;
run;

注意:在存在包含空格的文件名时,反转printf字符串中大小和路径的顺序将避免解析结果时出现问题。

答案 1 :(得分:0)

这可能会对您有所帮助。

%macro get_filenames(location);
filename _dir_ "%bquote(&location.)";
data filenames(keep=memname);
handle=dopen( '_dir_' );
if handle > 0 then do;
count=dnum(handle);
do i=1 to count;
memname=dread(handle,i);
output filenames;
end;
end;
rc=dclose(handle);
run;
filename _dir_ clear;
%mend;
%get_filenames(path)