Get list of files in directory under NOXCMD

1.4k views Asked by At

Can not use Xcommands in SAS EG. No access to SAS Management Console. How can I get a list of files in a directory without using Xcommands?

Tried DINFO but can only get 1 piece of info. Need a list of all files in the selected directory. Am I missing something here?

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;
3

There are 3 answers

2
Bendy On

I've not used Enterprise Guide but how about using a pipe'd filename? You cn then use that with the infile statement to put the result of the query into a dataset...

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

data dirlist ;
    infile dirlist ;
    format fname $300. ;
    input fname $ ;
run;
0
Robert Penridge On

Here's a couple of macros we use to do this. The main macro is %file_list but it also requires the %isDir macro in order to run. Some usage examples:

%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 macro definition:

/******************************************************************************
** 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 macro definition:

/******************************************************************************
** 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; 
0
crow16384 On
%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;

This works fine. I use &name for other macro and do something with files... (load from CSV, for example).