BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Citrine10
Obsidian | Level 7

Hi there

I have code that checks and lists files in a directory. I would like to do a check to see if there are less than 5 files it should continue else if there are more than 5 files it should delete the extra files and exit. 

How do I implement that?

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

How to delete files from a list of files:

 

*list of files to take an action on;
data test;
infile datalines;
input file_nm $50.;
datalines;
/home/users/temp1.sas7bndx
/home/users/temp2.sas7bndx
/home/users/temp3.sas7bndx
/home/users/temp4.sas7bndx
/home/users/temp5.sas7bndx
/home/users/temp6.sas7bndx
;
run;

*action to do per file - delete file in this case;
%macro check(del_file);
%if %sysfunc(fileexist(&del_file)) ge 1 %then %do;
%let rc=%sysfunc(filename(temp, &del_file));
%let rc=%sysfunc(fdelete(&temp));
%end;
%else %put The file &file does not exist;
%mend check;

*call macro for each file;
data _null_;
set test;

str = catt('%check(', file_nm, ');');

call execute(str);

run;

View solution in original post

17 REPLIES 17
japelin
Rhodochrosite | Level 12
Is the file you are referring to a SAS data set or a file on the OS?
Also, is the code SAS? Is it a shell script (command, batch, PowerShell, etc.)?
What exactly are the extra files? Are they sorted by date, by name, or by file size?
Does it terminate when it's done checking one target directory? Or does it check recursively?

The question is too vague, so please organize it a little better.
Citrine10
Obsidian | Level 7

there are .log files and .xlsx files in the directory. It is a file directory. 

Yes the code is SAS.

Files are not sorted by anything. I dont need any sorting etc. 

japelin
Rhodochrosite | Level 12

I'm not sure what kind of code you have, but you can use
1. save the list of files into a dataset with their file paths.
2. If there are more than 5 obs, delete them based on the file path.

 

For example:

/* start create test files */
%Macro MTestFileCreate;
  %do i=1 %to 10;
  filename f "C:\Temp\extrafile&i..log";
  data _null_;
    file f;
    put 'sample';
  run;
  %end;
%Mend;
%MTestFileCreate;
data filelist;
  length path $200;
  do i=1 to 10;
    path=cats("C:\Temp\extrafile",i,".log");
    output;
  end;
  drop i;
run;
/* end create test files */
data _null_;
  set filelist;
  rc=filename('del',path);
  if _n_>5 then rc=fdelete('del');
run;
Citrine10
Obsidian | Level 7

Hi

thank you for the above. I tried the code but it does not work. it does not delete the files 😞

Alternatively, I tried getting only 5 records from the list of files and thereafter decided to remove the remaining files however I am struggling with the delete and the if statement. 

 

japelin
Rhodochrosite | Level 12
How are you getting the file list in your code?
If you show the code, I can advise you.
Citrine10
Obsidian | Level 7

I have a macro that lists all the files and I call it 

 

%macro list_files(dir,ext);
	%local filrf rc did memcnt name i;
	%let rc=%sysfunc(filename(filrf,&dir));
	%let did=%sysfunc(dopen(&filrf));
	%if %sysfunc(exist(tables)) = 1 %then
		%do;
			proc sql;
				drop table tables;
			quit;
		%end;
	%if &did eq 0 %then
		%do;
			%put Directory &dir cannot be open or does not exist;
			%return;
		%end;
	%do i = 1 %to %sysfunc(dnum(&did));
		%let name=%qsysfunc(dread(&did,&i));
		%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then
			%do;
				%put &dir\&name;
				data _tmp;
					length dir $512 name $100 ext $100;
					dir=symget("dir");
					name=symget("name");
					ext=upcase("&ext.");
				run;
				proc append base=tables data=_tmp;
				run;
				quit;
			%end;
		%else %if %qscan(&name,2,.) = %then
			%do;
			%end;
	%end;
	%let rc=%sysfunc(dclose(&did));
	%let rc=%sysfunc(filename(filrf));
	proc sql;
		drop table _TMP;
	quit;
%mend list_files;

 

 

------------------------------------------------------------------

I call the macro :

include "/C:/list_files.sas";

/*file paths*/
%let path_in= /myfiles;

/*List of files*/
%list_files("&path_in",xlsx)

proc sql;
create table allfiles as
select * from tables;
quit;

proc sql;
create table FileCount as
select count(name) into: Filecount from tables;
quit;

Now this is where I need it to do a check to see if there are more then 5 files in the directory then delete them and exit, if there are less than 5 files, then continue

Quentin
Super User
If the directory has more than 5 files, and you want to delete the "extra" files, how do you determine which files to delete?
BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Citrine10
Obsidian | Level 7

Yes correct. it can be any of the files

Quentin
Super User

I suggest reviewing:

https://blogs.sas.com/content/sgf/2018/07/17/delete-sas-logs-admin/

 

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Citrine10
Obsidian | Level 7
Thank you Quentin, that is very useful. Do you know where I can put a check to see if there are more than 5 files then delete them and exit else continue?
Quentin
Super User

I would approach this in chunks.

 

Are you happy with your %listfiles macro?  If so, then you've got a dataset that lists all the files in the directory.

 

I would next write a %deletefile() macro which allows you to pass it a list of files to be deleted.  I would use the blog post as a guide for approaches to writing that macro.

 

Once you have %deletefiles done, then you can run your code like you have it to get a dataset of files, and you can check that dataset to see if it has more then 5 files, and if it does, you can use %deletefiles to delete the extras.

 

Or since you said you don't care which files are deleted, maybe you could do something quick like (untested pseudo-code):

data _null_;
    set tables; *your dataset listing all the files found in the directory;
    if _n_>5;
    rc=filename(fname, cats(dir,name,ext)); 
    rc=fdelete(fname);
run;

 

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Citrine10
Obsidian | Level 7

thank you Quentin, you are really helping me get there 🙂

 

i have a macro that deletes a file from a directory and when testing with one file, it works however when I try to pass it through the code it doesnt work. It only shows me the remaining list which should be deleted yet it doesnt delete

%macro delfile(file);
%if %sysfunc(fileexist(&file)) ge 1 %then %do;
   %let rc=%sysfunc(filename(temp,&file));
   %let rc=%sysfunc(fdelete(&temp));
%end; 
%else %put The file &file does not exist;
%mend check;


/*lists all files to delete*/
data list;
set allfiles; *your dataset listing all the files found in the directory;
if _n_>5;
rc=filename(fname, cats(dir,name,ext));
rc=fdelete(fname);
%delFile(&fullpath);
run;
japelin
Rhodochrosite | Level 12

how about this before use %delfile.

I think filename and fdelete function in datastep needs quoted fileref.

 

data list;
set allfiles; *your dataset listing all the files found in the directory;
if _n_>5;
rc=filename('fname', cats(dir,name,ext)); 
rc=fdelete('fname');
run;

 

 

Reeza
Super User

How to delete files from a list of files:

 

*list of files to take an action on;
data test;
infile datalines;
input file_nm $50.;
datalines;
/home/users/temp1.sas7bndx
/home/users/temp2.sas7bndx
/home/users/temp3.sas7bndx
/home/users/temp4.sas7bndx
/home/users/temp5.sas7bndx
/home/users/temp6.sas7bndx
;
run;

*action to do per file - delete file in this case;
%macro check(del_file);
%if %sysfunc(fileexist(&del_file)) ge 1 %then %do;
%let rc=%sysfunc(filename(temp, &del_file));
%let rc=%sysfunc(fdelete(&temp));
%end;
%else %put The file &file does not exist;
%mend check;

*call macro for each file;
data _null_;
set test;

str = catt('%check(', file_nm, ');');

call execute(str);

run;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 17 replies
  • 917 views
  • 5 likes
  • 4 in conversation