BookmarkSubscribeRSS Feed
Mot3ku
Calcite | Level 5

Hi,

 

I would like to create a list of information about every file that is readable in a catalog/subcatalog within specified directory. 
The informations i want to get are:
- Create date, modification date, owner, size and path to the file. 

I managed to create a code: 

%macro list_files(path);

	%local fileref did memcnt i fid rc moddate crdate owner size filepath fullpath;

	data file_into;
		length filepath $256 filename $256 owner $100 crdate $30 moddate $30 size 8;
		format size comma20.0;
		stop;
	run;

	%let rc=%sysfunc(filename(filrf,&path));
	%let did=%sysfunc(dopen(&filrf));  

	%if &did > 0 %then %do;
		%let memcnt = %sysfunc(dnum(&did));

		%do i = 1 %to &memcnt;
			%let filename = %sysfunc(dread(&did, &i));
			%let fullpath = &path/&filename;

			%if %sysfunc(fileexist("&fullpath")) %then %do;
				%let fid = %sysfunc(fopen("&fullpath"));

				%if &fid > 0 %then %do;
					%let size = %sysfunc(input(finfo(fid, 'File Size (bytes)'), 20.));
					%let crdate = %sysfunc(finfo(fid, 'Create Time'));
					%let moddate = %sysfunc(finfo(&fid, 'Last Modified'));
					%let owner = %sysfunc(finfo(fid, 'Owner Name'));

					data file_into;
						set file_into;
						filepath = "&fullpath";
						filename = "&filename";
						owner = "&owner";
						size = "&size";
						crdate = "&crdate";
						moddate = "&moddate";
						output;
						if last then do;
							call symput('file_count', _N_);
						end;
					run;

					%let rc = %sysfunc(fclose(&fid));
				%end;
			%end;
			%else %do;
				%list_files(&fullpath);
			%end;
		%end;
		%let rc = %sysfunc(dclose(&did));
	%end;
	%else %do;
		%put "ERROR: Could not open directory &path";
	%end;
%mend list_files;

Unfortunately, there is no result at all. Sometimes when the catalogs name is big I get a note:
"In a call to the FOPEN routine, the fileref (...) exceeds 8 characters, and will be truncated.

 

But even if there is a file (at the top level of specified &path) I get no information back about it. 

 

Maybe someone ever tried making such a code and would be open to help me.

5 REPLIES 5
Tom
Super User Tom
Super User

The FILEREF is just a nickname to use to reference the file (or directory).  It does not have to look anything at all like the actual filename.  So the 8 character limit should not be any real concern.

 

Why are you using the %SYSFUNC() macro function to call SAS functions in macro code and then running a data step to transfer values back from macro variables into actual variables? Why didn't you just use the data step to call the SAS functions directly storing the results directly into variables?

 

If you want to get a list of all of the files in a directory you can use this macro:  https://github.com/sasutils/macros/blob/master/dirtree.sas

 

That macro uses a data step to call the various functions (FOPEN, DOPEN, FINFO etc.).  And it uses a MODIFY statement to let basically implement recursion into the sub directories.

 

ballardw
Super User

Your question mentions "catalog/subcatalog within specified directory". By Catalog do you mean a SAS Catalog, which is a pretty specific type of file or something else? Contents of SAS catalogs are going to need somewhat different tools than the external files.

 

FOPEN expects to see a FILEREF, not an FILENAME. So you associate a fileref with the file using the FILENAME statement prior to the FOPEN.

Strings in macro function calls, including %sysfunc, should not include quotes unless the actual value has quotes. Does your filename have quotes at the operating system level.

%if %sysfunc(fileexist(&fullpath)) %then %do;
%let rc=%sysfunc(filename(myfile, &fullpath));
%let fid=%sysfunc(fopen(myfile));

 

yabwon
Onyx | Level 15

I'd recommend using the BasePlus package, in particular the %dirsandfiles() macro. The macro gives you the list of files and sub-directories (with content) plus all that "metadata" stuff. It works OS independent, so on Win/Linux/UNIX. 

 

This article, Appendix B, page 20, gives you quick instruction on how to install and use the package.

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Kurt_Bremser
Super User

Several things:

  • FOPEN expects a file reference as its argument, not a file name; create the fileref with a FILENAME function
  • you create the dataset file_into with zero observations; this means that the SET statement in your DATA step will immediately try to read past the end, so the step is terminated
  • if your goal is to store all the file metadata in a dataset, all that macro coding is unnecessary; use a DO loop in the DATA step with an OUTPUT in it
Kurt_Bremser
Super User

PS this presentation contains examples for using the file functions; up to a single DATA step which reads a complete directory tree.

 

PPS don't expect a "create timestamp" if you run this on UNIX; UNIX has only modification timestamps.

sas-innovate-white.png

Missed SAS Innovate in Orlando?

Catch the best of SAS Innovate 2025 — anytime, anywhere. Stream powerful keynotes, real-world demos, and game-changing insights from the world’s leading data and AI minds.

 

Register now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 1035 views
  • 1 like
  • 5 in conversation