使用SAS循环遍历目录并将某些文件名放入数据集中

时间:2016-05-02 19:16:14

标签: sas

我使用下面的代码遍历目录并查找每个子文件夹中的所有.xlsx文件。我需要调整它以获取每个找到的文件的路径,并在运行时将其堆叠到数据集中。

data thisfile;
    set _NULL_;
run;
%macro drive(dir,ext);                                                                                                                  
%local filrf rc did memcnt name i;                                                                                                    

  /* Assigns a fileref to the directory and opens the directory */                                                           
  %let rc=%sysfunc(filename(filrf,&dir));                                                                                               
  %let did=%sysfunc(dopen(&filrf));                                                                                                     

  /* Make sure directory can be open */                                                                                                 
  %if &did eq 0 %then %do;                                                                                                              
   %put Directory &dir cannot be open or does not exist;                                                                                
   %return;                                                                                                                             
  %end;                                                                                                                                 

   /* Loops through entire directory */                                                                                                 
   %do i = 1 %to %sysfunc(dnum(&did));                                                                                                  

     /* Retrieve name of each file */                                                                                                   
     %let name=%qsysfunc(dread(&did,&i));                                                                                               

 /* Checks to see if the extension matches the parameter value */                                                                   
 /* If condition is true print the full name to the log        */                                                                   
  %if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;                                                                       
    %put &dir\&name;

    data thisfile_&i.;
    format filename $100.;
        set thisfile;
    filename = "&dir.\&name.";
    run;                                                                                                                
  %end;                                                                                                                             
 /* If directory name call macro again */                                                                                           
  %else %if %qscan(&name,2,.) = %then %do;                                                                                          
    %drive(&dir\%unquote(&name),&ext)                                                                                               
  %end;                                                                                                                             

  %end;                                                                                                                                

/* Closes the directory and clear the fileref */                                                                                      
%let rc=%sysfunc(dclose(&did));                                                                                                       
%let rc=%sysfunc(filename(filrf));                                                                                                    

%mend drive;                                                                                                                            

/* First parameter is the directory of where your files are stored. */                                                                  
/* Second parameter is the extension you are looking for.           */                                                                  
%drive(v:\,xlsx)

代码按预期工作,但我需要行'%put& dir \& name;'的结果输入到数据集而不是仅打印到日志,以便在代码完成运行时,我将有一个数据集,每个.xlsx文件有一个观察。

这看起来很简单,但当我尝试创建数据集并使用& dir \& name初始化'filename'变量时,我得到一个零观察数据集。我的日志结果表明宏参数工作正常,但它没有写出观察结果:

MPRINT(DRIVE):   data thisfile_1;
MPRINT(DRIVE):   format filename $100.;
MPRINT(DRIVE):   set thisfile;
MPRINT(DRIVE):   filename = "v:\\MYFILENAME.xlsx";
MPRINT(DRIVE):   run;

NOTE: There were 0 observations read from the data set WORK.THISFILE.
NOTE: The data set WORK.THISFILE_1 has 0 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time           0.03 seconds
      cpu time            0.01 seconds

我知道编写的代码不会将我的所有结果“堆叠”到一个集合中,但我只是想让它运行起来。

2 个答案:

答案 0 :(得分:1)

为什么你有一个'SET'。删除它并尝试查看您的数据是否按照您希望的方式创建。您可以在末尾添加proc附加以附加所有数据集或使用快捷方式数据引用thisfile:来附加它们。

data thisfile_&i.;
format filename $100.;
filename = "&dir.\&name.";
run; 

宏外:

data all_files;
 set thisfile:;
run;

答案 1 :(得分:0)

如果您想在数据步骤中得到结果,那么只需在数据步骤中调用函数。

%macro drive(dir,ext,dsn);
data &dsn ;
  length dname $256 fname $256 ;
  keep dname fname ;
  dname=symget('dir');
  length filrf $8 ;
  rc=filename(filrf,dname);
  did=dopen(filrf);
  if did then do i=1 to dnum(did);
    fname=dread(did,i);
    if index(fname,'.') and upcase(scan(fname,-1,'.'))=%upcase("&ext") then output;
  end;
  else put 'ERROR: Directory ' dname=:$quote. 'cannot be opened.';
  rc=filename(filrf);
run;
%mend drive;

%drive(dir=~/test,ext=xlsx,dsn=out)