<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic How to write sas program to read all files from directory and subdirectory in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-sas-program-to-read-all-files-from-directory-and/m-p/553531#M153945</link>
    <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;Below macro read files from directory but i want to add code so it can read files from sub-directory&lt;BR /&gt;&lt;BR /&gt;What can i do &lt;BR /&gt;%macro dir_contents(&lt;BR /&gt;dir= /* directory name to process */&lt;BR /&gt;, ext= /* optional extension to filter on */&lt;BR /&gt;, dsout=work.dir_contents /* dataset name to hold the file names */&lt;BR /&gt;, attribs=N /* get file attributes? (Y/N ) */&lt;BR /&gt;); &lt;BR /&gt;&lt;BR /&gt;%global _dir_fileN;
           %local _syspathdlim _exitmsg _attrib_vars;
           %* verify the required parameter has been provided. ;
            %if %length(&amp;amp;dir) = 0 %then %do;
             %let _exitmsg = %str(E)RROR: No directory name specified - macro will exit.;
 %goto finish;
%end;
%* verify existence of the requested directory name. ;
%if %sysfunc(fileexist(&amp;amp;dir)) = 0 %then %do;
 %let _exitmsg = %str(E)RROR: Specified input location, &amp;amp;dir., does not exist - macro
will exit.;
 %goto finish;
%end;
%* set the separator character needed for the full file path: ;
%* (backslash for Windows, forward slash for UNIX systems) ;
%if &amp;amp;sysscp = WIN %then %do;
 %let _syspathdlim = \;
%end;
%else %do;
 %let _syspathdlim = /;
%end;
/*--- begin data step to capture names of all file names found in the specified
directory. ---*/
data &amp;amp;dsout(keep=file_seq basefile pathname);
 length basefile $ 40 pathname $ 1000 _msg $ 1000;
 /* Allocate directory */
 rc=FILENAME('xdir', "&amp;amp;dir");

 if rc ne 0 then do;
 _msg = "E" || 'RROR: Unable to assign fileref to specified directory. ' ||
sysmsg();
 go to finish_datastep;
 end;
 /* Open directory */
 dirid=DOPEN('xdir');
 if dirid eq 0 then do;
 _msg = "E" || 'RROR: Unable to open specified directory. ' || sysmsg();
 go to finish_datastep;
 end;

  /* Get number of information items */
 nfiles=DNUM(dirid);
 do j = 1 to nfiles;
 basefile = dread(dirid, j);
 pathname=strip("&amp;amp;dir") || "&amp;amp;_syspathdlim." || strip(basefile);

 %if %length(&amp;amp;ext) %then %do;
/* scan the final "word" of the full file name, delimited by dot character. */

 ext = scan(basefile,-1,'.');
 if ext="&amp;amp;ext." then do;
 file_seq + 1;
 output;
 end;
 %end;
 %else %do;
 file_seq + 1;
 output;
 %end;
 end;
 /* Close the directory */
 rc=DCLOSE(dirid);
 /* Deallocate the directory */
 rc=FILENAME('xdir');

 call symputx('_dir_fileN', file_seq);
 finish_datastep:
 if _msg ne ' ' then do;
 call symput('_exitmsg', _msg);
 end;
run;
%if %upcase(&amp;amp;attribs)=Y and &amp;amp;_dir_fileN &amp;gt; 0 %then %do;
 data _file_attr(keep=file_seq basefile infoname infoval);
 length infoname infoval $ 500;
 set &amp;amp;dsout.;
/* open each file to get the additional attributes available. */
 rc=filename("afile", pathname);
 fid=fopen("afile");
/* return the number of system-dependent information items available for the
external file. */
 infonum=foptnum(fid);
/* loop to get the name and value of each information item. */
 do i=1 to infonum;
 infoname=foptname(fid,i);
 infoval=finfo(fid,infoname);
 if upcase(infoname) ne 'FILENAME' then output;
 end;
 close=fclose(fid);
 run;
 /* transpose each information item into its own variable */
 proc transpose data=_file_attr out=trans_attr(drop=_:) ;
 by file_seq basefile ;
 var infoval;
 id infoname;
 run;

 proc sql noprint;
 select distinct name into : _attrib_vars separated by ', '
 from dictionary.columns
 where memname='TRANS_ATTR' and upcase(name) not in('BASEFILE', 'FILE_SEQ')
 order by varnum;
 quit;
 /* merge back the additional attributes to the related file name. */
 data &amp;amp;dsout.;
 merge &amp;amp;dsout. trans_attr;
 by file_seq basefile;
 run;
 proc datasets nolist memtype=data lib=work;
 delete _file_attr trans_attr;
 run;
 quit;
%end;
%if %length(&amp;amp;_exitmsg) = 0 %then
%let _exitmsg = NOTE: &amp;amp;dsout created with &amp;amp;_dir_fileN. file names ;
%if %length(&amp;amp;ext) %then
%let _exitmsg = &amp;amp;_exitmsg where extension is equal to &amp;amp;ext.;
%let _exitmsg = &amp;amp;_exitmsg from &amp;amp;dir..;
%finish:
%put &amp;amp;_exitmsg;
%if %length(&amp;amp;_attrib_vars) ne 0 %then %do;
 %put;
 %put NOTE: File attributes were requested and have been added to &amp;amp;dsout.. Variable
names are &amp;amp;_attrib_vars.;
%end;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 24 Apr 2019 06:17:12 GMT</pubDate>
    <dc:creator>sam1231</dc:creator>
    <dc:date>2019-04-24T06:17:12Z</dc:date>
    <item>
      <title>How to write sas program to read all files from directory and subdirectory</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-sas-program-to-read-all-files-from-directory-and/m-p/553531#M153945</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;Below macro read files from directory but i want to add code so it can read files from sub-directory&lt;BR /&gt;&lt;BR /&gt;What can i do &lt;BR /&gt;%macro dir_contents(&lt;BR /&gt;dir= /* directory name to process */&lt;BR /&gt;, ext= /* optional extension to filter on */&lt;BR /&gt;, dsout=work.dir_contents /* dataset name to hold the file names */&lt;BR /&gt;, attribs=N /* get file attributes? (Y/N ) */&lt;BR /&gt;); &lt;BR /&gt;&lt;BR /&gt;%global _dir_fileN;
           %local _syspathdlim _exitmsg _attrib_vars;
           %* verify the required parameter has been provided. ;
            %if %length(&amp;amp;dir) = 0 %then %do;
             %let _exitmsg = %str(E)RROR: No directory name specified - macro will exit.;
 %goto finish;
%end;
%* verify existence of the requested directory name. ;
%if %sysfunc(fileexist(&amp;amp;dir)) = 0 %then %do;
 %let _exitmsg = %str(E)RROR: Specified input location, &amp;amp;dir., does not exist - macro
will exit.;
 %goto finish;
%end;
%* set the separator character needed for the full file path: ;
%* (backslash for Windows, forward slash for UNIX systems) ;
%if &amp;amp;sysscp = WIN %then %do;
 %let _syspathdlim = \;
%end;
%else %do;
 %let _syspathdlim = /;
%end;
/*--- begin data step to capture names of all file names found in the specified
directory. ---*/
data &amp;amp;dsout(keep=file_seq basefile pathname);
 length basefile $ 40 pathname $ 1000 _msg $ 1000;
 /* Allocate directory */
 rc=FILENAME('xdir', "&amp;amp;dir");

 if rc ne 0 then do;
 _msg = "E" || 'RROR: Unable to assign fileref to specified directory. ' ||
sysmsg();
 go to finish_datastep;
 end;
 /* Open directory */
 dirid=DOPEN('xdir');
 if dirid eq 0 then do;
 _msg = "E" || 'RROR: Unable to open specified directory. ' || sysmsg();
 go to finish_datastep;
 end;

  /* Get number of information items */
 nfiles=DNUM(dirid);
 do j = 1 to nfiles;
 basefile = dread(dirid, j);
 pathname=strip("&amp;amp;dir") || "&amp;amp;_syspathdlim." || strip(basefile);

 %if %length(&amp;amp;ext) %then %do;
/* scan the final "word" of the full file name, delimited by dot character. */

 ext = scan(basefile,-1,'.');
 if ext="&amp;amp;ext." then do;
 file_seq + 1;
 output;
 end;
 %end;
 %else %do;
 file_seq + 1;
 output;
 %end;
 end;
 /* Close the directory */
 rc=DCLOSE(dirid);
 /* Deallocate the directory */
 rc=FILENAME('xdir');

 call symputx('_dir_fileN', file_seq);
 finish_datastep:
 if _msg ne ' ' then do;
 call symput('_exitmsg', _msg);
 end;
run;
%if %upcase(&amp;amp;attribs)=Y and &amp;amp;_dir_fileN &amp;gt; 0 %then %do;
 data _file_attr(keep=file_seq basefile infoname infoval);
 length infoname infoval $ 500;
 set &amp;amp;dsout.;
/* open each file to get the additional attributes available. */
 rc=filename("afile", pathname);
 fid=fopen("afile");
/* return the number of system-dependent information items available for the
external file. */
 infonum=foptnum(fid);
/* loop to get the name and value of each information item. */
 do i=1 to infonum;
 infoname=foptname(fid,i);
 infoval=finfo(fid,infoname);
 if upcase(infoname) ne 'FILENAME' then output;
 end;
 close=fclose(fid);
 run;
 /* transpose each information item into its own variable */
 proc transpose data=_file_attr out=trans_attr(drop=_:) ;
 by file_seq basefile ;
 var infoval;
 id infoname;
 run;

 proc sql noprint;
 select distinct name into : _attrib_vars separated by ', '
 from dictionary.columns
 where memname='TRANS_ATTR' and upcase(name) not in('BASEFILE', 'FILE_SEQ')
 order by varnum;
 quit;
 /* merge back the additional attributes to the related file name. */
 data &amp;amp;dsout.;
 merge &amp;amp;dsout. trans_attr;
 by file_seq basefile;
 run;
 proc datasets nolist memtype=data lib=work;
 delete _file_attr trans_attr;
 run;
 quit;
%end;
%if %length(&amp;amp;_exitmsg) = 0 %then
%let _exitmsg = NOTE: &amp;amp;dsout created with &amp;amp;_dir_fileN. file names ;
%if %length(&amp;amp;ext) %then
%let _exitmsg = &amp;amp;_exitmsg where extension is equal to &amp;amp;ext.;
%let _exitmsg = &amp;amp;_exitmsg from &amp;amp;dir..;
%finish:
%put &amp;amp;_exitmsg;
%if %length(&amp;amp;_attrib_vars) ne 0 %then %do;
 %put;
 %put NOTE: File attributes were requested and have been added to &amp;amp;dsout.. Variable
names are &amp;amp;_attrib_vars.;
%end;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 24 Apr 2019 06:17:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-sas-program-to-read-all-files-from-directory-and/m-p/553531#M153945</guid>
      <dc:creator>sam1231</dc:creator>
      <dc:date>2019-04-24T06:17:12Z</dc:date>
    </item>
    <item>
      <title>Re: How to write sas program to read all files from directory and subdirectory</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-sas-program-to-read-all-files-from-directory-and/m-p/553560#M153954</link>
      <description>&lt;P&gt;Crushing peanuts with an elephant's hoof. This can be achieved in a much simpler way by using the power of your operating system:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;filename oscmd pipe "find /path -name \*.csv";

data _null_;
infile oscmd;
input;
call execute('%nrstr(%import_file(' !! strip(_infile_) !! '))');
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;if you have a macro for importing a single file. Expand this step as needed.&lt;/P&gt;</description>
      <pubDate>Wed, 24 Apr 2019 09:09:41 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-sas-program-to-read-all-files-from-directory-and/m-p/553560#M153954</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2019-04-24T09:09:41Z</dc:date>
    </item>
    <item>
      <title>Re: How to write sas program to read all files from directory and subdirectory</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-sas-program-to-read-all-files-from-directory-and/m-p/553661#M153976</link>
      <description>&lt;PRE&gt;&amp;nbsp;&lt;SPAN class="token macroname"&gt;%let&lt;/SPAN&gt; _exitmsg &lt;SPAN class="token operator"&gt;=&lt;/SPAN&gt; &lt;SPAN class="token macrostatement"&gt;%str&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;(&lt;/SPAN&gt;E&lt;SPAN class="token punctuation"&gt;)&lt;/SPAN&gt;RROR &lt;BR /&gt;&lt;BR /&gt;if rc ne 0 then do;
 _msg = &lt;STRONG&gt;&lt;FONT color="#ff0000"&gt;"E" || 'RROR&lt;/FONT&gt;&lt;/STRONG&gt;: Unable to assign fileref to specified directory. ' ||
sysmsg();
&lt;/PRE&gt;
&lt;P&gt;??????&amp;nbsp;Why the %str?&amp;nbsp;&amp;nbsp; Why "E"|| 'RROR:&amp;nbsp; ???&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Suggest also looking at the CAT functions instead of || operator for concatenating&lt;/P&gt;</description>
      <pubDate>Wed, 24 Apr 2019 14:46:30 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-sas-program-to-read-all-files-from-directory-and/m-p/553661#M153976</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2019-04-24T14:46:30Z</dc:date>
    </item>
  </channel>
</rss>

