- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I am attempting to collect all of the csv files in a folder using the filename and pipe statements. I can get it to work when I directly specify what the dir is, but wondered if I could have it inserted through a macro.
The code that I think should work is:
1 %macro um;
2 %let source = C:\Users\Home\Folder;
3 %let me = %quote(%'dir %"&source\*.csv%" %');
4 %let rex = %bquote(filename DIRLIST pipe &me.);
5 filename DIRLIST pipe &me.;
6 &rex;
7 data dirlist ;
8 infile dirlist lrecl=200 truncover;
9 input line $200.;
10 if input(substr(line,1,10), ?? mmddyy10.) = . then delete;
11 parse = substr(line,40,50 );
12 file_name = substr(parse,1,length(parse)-4);
13 keep file_name parse;
14 run;
15 %mend;
16 %um;
I highlighted in blue where the lines should be inserted inside of quotation marks. For reference line 5 and 6 should duplicate the same text, which would be
filename dirlist pipe 'dir "C:\Users\Home\Folder\*.csv" ';
But when I run it, it always gives me the error "ERROR: Error in the FILENAME statement.". It seems that the main issue here is the use of unbalanced quotation marks in the macro, otherwise I could simply have it written as filename dirlist pipe 'dir "&source.\*.csv" '; But this statement because I have not specified %quote absorbs the parentheses. Any advice on how to have this run correctly would be appreciated.
Thanks
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Using SAS Macro to pipe a list of filenames from a Windows directory - Stack Overflow
Here's a whole bunch of different solutions to the same question. Hopefully one works for you
One other thing, I'm surprised to not see a scan function in your code to get the file name.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You are likely attempting to generate way too many quotes to begin with.
filename dirlist pipe "dir &source.\*.csv"; should work as the DIR command doesn't require the path to be in quotes. However you may want to check this link for possible other issues: http://support.sas.com/kb/41/863.html
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
If I remove the quotes (' ')from the dir statement I am given this response
ERROR: Error in the FILENAME statement.
ERROR 23-2: Invalid option name dir.
I agree that the cause of the problem is adding two sets of quotation marks, but wondered if anyone had an idea of how to either do this in more steps so the macro wouldn't crash, or another way to have program read the quotation marks correctly. Of note I can get it to insert the correct line into the macro, but then the filename statement doesn't run correctly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I'm assuming you're trying to get a list of CSV files from a directory, and assuming you're on Windows?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Correct on both accounts
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Using SAS Macro to pipe a list of filenames from a Windows directory - Stack Overflow
Here's a whole bunch of different solutions to the same question. Hopefully one works for you
One other thing, I'm surprised to not see a scan function in your code to get the file name.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the advice, the scan function was written farther down in the macro and I cut it off at reading the file names into table so there wouldn't be unnecessary code. But here is what the code looks like once I implemented your suggestions and it is working now.
%LET source = C:\Users\Home\Documents\;
%LET library = out;
libname &library "&source";
%macro daily(type = );
%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(&source);
data dirlist ;
set filenames;
if substr(memname,length(memname)-2,3) ~="&type" then delete;
parse = substr(memname,1,length(memname)-4);
file_name = memname;
keep file_name parse;
run;
proc sql noprint;
select parse, file_name
into :parse_list separated by '*', :file_list separated by '*'
from dirlist;
quit;
%let cntlist = &sqlobs;
%do i = 1 %to &cntlist;
%let parse = %scan(&parse_list.,&I.,"*");
%let file = %scan(&file_list.,&I.,"*");
proc import out=daily_&i
datafile="&source\&parse"
dbms=csv replace;
getnames=yes;
guessingrows=10000;
run;
%end;
%mend;
%daily(type = txt);