Кажущийся вызов макроса не разрешен в канале имени файла sas - PullRequest
0 голосов
/ 24 января 2019

Я использую следующий код 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 голосов
/ 24 января 2019

Макропроцессор будет искать макро-триггеры & и % внутри строк, заключенных в двойные кавычки, но не те, которые заключены в одинарные кавычки.Вы можете использовать функцию 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 позволит избежать проблем с анализом результатов при наличии имен файлов со встроенными пробелами.

0 голосов
/ 24 января 2019

Это может вам помочь.

%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)
...