【问题标题】:Get list of files in directory under NOXCMD获取NOXCMD目录下的文件列表
【发布时间】:2015-06-12 12:26:45
【问题描述】:

不能在 SAS EG 中使用 Xcommands。无权访问 SAS 管理控制台。如何在不使用 Xcommands 的情况下获取目录中的文件列表?

尝试了 DINFO,但只能获得 1 条信息。需要选定目录中所有文件的列表。我在这里遗漏了什么吗?

data a;
  rc=filename("mydir", c:\");
  put "rc = 0 if the directory exists: " rc=;
  did=dopen("mydir");
  put did=;
  numopts=doptnum(did);
  put numopts=;

  do i = 1 to numopts;
    optname = doptname(did,i);
    put i= optname=;
    optval=dinfo(did,optname);
    put optval=;
    output;
  end;
run;

【问题讨论】:

  • 你应该可以使用可怕的dread() 功能。类似于doptname(),但循环遍历目录的成员。
  • 干杯杰夫。尽管没有许多文件变量,但这很有效。只需使用 1 ro 1000 或 filename = blank 即可结束循环。
  • 这是我使用的代码。我把其他东西放在那里,以防有人能建议我如何获取文件数量并在循环控制中使用它。数据文件名; rc=filename("mydir", "c:\"); put "rc = 0 如果目录存在:" rc=;没有=dopen(“我的目录”);把做=; numopts=doptnum(did);把 numopts=; do i = 1 to 1000 /*numopts*/; optname = doptname(did,i);把 i= optname=; optval=dinfo(did,optname);把 optval=;文件名=恐惧(做,我);把文件名=;如果文件名 = '' 那么 i=1000; /* 结束循环。 /否则输出; / 写出文件名 */ end;运行;
  • 仅供参考,XCMD 在 EG 中是可能的;'只是服务器默认设置为不允许它(options noxcmd)。如果您的服务器管理员愿意,可以启用它。

标签: sas enterprise-guide


【解决方案1】:

我没有使用过企业指南,但是使用pipe'd 文件名怎么样?然后您将其与infile 语句一起使用,将查询结果放入数据集中...

filename dirlist pipe "ls /<your-path>/*";

data dirlist ;
    infile dirlist ;
    format fname $300. ;
    input fname $ ;
run;

【讨论】:

【解决方案2】:

这是我们用来执行此操作的几个宏。主宏是%file_list,但它还需要%isDir 宏才能运行。一些使用示例:

%put %file_list(iPath=e:\blah\); * TEST AGAINST A DIR THAT DOESNT EXIST;
%put %file_list(iPath=e:\SASDev); * TEST AGAINST A DIR THAT EXISTS;
%put %file_list(iPath=e:\SASDev\,iFiles_only=1); * LIST ONLY FILES;
%put %file_list(iPath=e:\sasdev\,iFiles_only=1,iFilter=auto); * FILTER TO ONLY FILES THAT CONTAIN THE STRING AUTO;

%isDir宏定义:

/******************************************************************************
** PROGRAM:  CMN_MAC.ISDIR.SAS
**
** DESCRIPTION: DETERMINES IF THE SPECIFIED PATH EXISTS OR NOT.
**              RETURNS: 0 IF THE PATH DOES NOT EXIST OR COULD NOT BE OPENED.
**                       1 IF THE PATH EXISTS AND CAN BE OPENED.
**
** PARAMETERS: iPath: THE FULL PATH TO EXAMINE.  NOTE THAT / AND \ ARE TREATED
**                    THE SAME SO &SASDIR/COMMON/MACROS IS THE SAME AS
**                    &SASDIR\COMMON\MACROS.
**
******************************************************************************/

%macro isDir(iPath=,iQuiet=1);
  %local result dname did rc;

  %let result = 0;
  %let check_file_assign =  %sysfunc(filename(dname,&iPath));

  %put ASSIGNED FILEREF (0=yes, 1=no)? &check_file_assign &iPath;


  %if not &check_file_assign %then %do;

    %let did = %sysfunc(dopen(&dname));

    %if &did %then %do;
      %let result = 1;
    %end;
    %else %if not &iQuiet %then %do;
      %put &err: (ISDIR MACRO).;
      %put %sysfunc(sysmsg());
    %end;

    %let rc = %sysfunc(dclose(&did));

  %end;
  %else %if not &iQuiet %then %do;
    %put &err: (ISDIR MACRO).;
    %put %sysfunc(sysmsg());
  %end;

  &result

%mend;

%filelist宏定义:

/******************************************************************************
** PROGRAM:  MACRO.FILE_LIST.SAS
**
** DESCRIPTION: RETURNS THE LIST OF FILES IN A DIRECTORY SEPERATED BY THE
**              SPECIFIED DELIMITER. RETURNS AN EMPTY STRING IF THE THE 
**              DIRECTORY CAN'T BE READ OR DOES NOT EXIST.
**
** PARAMETERS: iPath: THE FULL PATH TO EXAMINE.  NOTE THAT / AND \ ARE TREATED
**                    THE SAME SO &SASDIR/COMMON/MACROS IS THE SAME AS
**                    &SASDIR\COMMON\MACROS. WORKS WITH BOTH UNIX AND WINDOWS.
**
******************************************************************************/
/*
** TODO. THERES ABOUT 100 WAYS THIS COULD BE IMPROVED SUCH AS SIMPLIFYING IF STATEMENTS FOR FILTERS...
*/
%macro file_list(iPath=, iFilter=, iFiles_only=0, iDelimiter=|);
  %local result did dname cnt num_members filename rc check_dir_exist check_file_assign;

  %let result=;

  %let check_dir_exist = %isDir(iPath=&iPath);
  %let check_file_assign = %sysfunc(filename(dname,&iPath));

  %put The desired path:  &iPath;
  %if &check_dir_exist and not &check_file_assign %then %do;

    %let did = %sysfunc(dopen(&dname));
    %let num_members = %sysfunc(dnum(&did));

    %do cnt=1 %to &num_members;

      %let filename = %qsysfunc(dread(&did,&cnt));
      %if "&filename" ne "" %then %do;

        %if "&iFilter" ne "" %then %do;
          %if %index(%lowcase(&filename),%lowcase(&iFilter)) eq 0 %then %do;
            %goto next;
          %end;
        %end;

        %if &iFiles_only %then %do;
          %if %isDir(iPath=%nrbquote(&iPath/&filename)) %then %do;
            %goto next;
          %end;
        %end;

        %let result = &result%str(&iDelimiter)&filename;

        %next:

      %end;
      %else %do;
        %put ERROR: (CMN_MAC.FILE_LIST) FILE CANNOT BE READ.;
        %put %sysfunc(sysmsg());
      %end;
    %end;

    %let rc = %sysfunc(dclose(&did));

  %end;
  %else %do;

    %put ERROR: (CMN_MAC.FILE_LIST) PATH DOES NOT EXIST OR CANNOT BE OPENED.;
    %put %sysfunc(sysmsg());

    %put DIRECTORY EXISTS (1-yes, 0-no)?  &check_dir_exist;
    %put ASSIGN FILEREF SUCCESSFUL (0-yes, 1-no)?  &check_file_assign;

  %end;

  /*
  ** RETURN THE RESULT.  TRIM THE LEADING DELIMITER OFF THE FRONT OF THE RESULTS.
  */
  %if "&result" ne "" %then %do;
    %qsubstr(%nrbquote(&result),2)
  %end;

%mend; 

【讨论】:

    【解决方案3】:
    %let path=C:\ETC;
    
    filename parent "&path\Data\CSV";
    
    data files;
       length file_name $50;
       drop rc did i;
       did=dopen("parent");
       if did > 0 then do;
         do i=1 to dnum(did);
           file_name=dread(did,i);
    
           output;
          end;
        rc=dclose(did);
        end;
       else put 'Could not open directory';
      run;
    
      * Some additions;
    
      %global name;
      %global count2;
    
      %let name=;
      %let count2=; 
      proc sql;
          select file_name into :name separated by '*' from work.files;
          %let count2 = &sqlobs;
      quit;
    

    这很好用。我将 &name 用于其他宏并对文件执行某些操作...(例如,从 CSV 加载)。

    【讨论】:

      猜你喜欢
      • 2017-02-24
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 2014-11-13
      相关资源
      最近更新 更多