BookmarkSubscribeRSS Feed
Carl_1234
Calcite | Level 5

This program searches for a specific string in various directories on my computer. After running it asks to input a string and also to select a specific directory. I just want this program to search all directories at once so that I don't have to select and search them one by one.

%global fnobs dir ext;
%let ext = SAS;  /*file extension*/
%let string = %UPCASE(&SEARCH_STRING);
%PUT &STRING;
proc datasets nolist;
delete all;
run;
%MACRO SETDIR;
%IF &DBSYS = CboTestEditValidation %THEN
%DO;
			%LET DBSYS=CBO_2324_TEST_EDIT_VALIDATION;
			%LET DIR=\\edw-fs02\CAE_Data\CBO\&Year\Programs;
%END;

%ELSE %IF &DBSYS = CBOSurveyReports %then %do;
	%let dbsys = CBO-Survey-Reports-Programs;
	%LET DIR=\\edw-fs02\CAE_Data\CBO\CBO Survey Reports\&Year;
%end;

%ELSE %IF &DBSYS = WDISPrograms %then %do;
	%let dbsys = WDIS;
	%LET DIR=\\edw-fs02\CAE_Data\WDIS\PRODUCTION\Survey Reports\&Year;
%end;

%ELSE %IF &DBSYS = SECCTEAppendixFF %then %do;
	%let dbsys = Appendix;
	%LET DIR=\\edw-fs02\CAE_Data\APPENDICES_WDIS_SECCTE\SECCTE\FF_appendixff_xls;
%end;

%ELSE %IF &DBSYS = SECCTEAppendixY %then %do;
	%let dbsys = Appendix;
	%LET DIR=\\edw-fs02\CAE_Data\APPENDICES_WDIS_SECCTE\SECCTE\Y_appendixy_xls;
%end;

%ELSE %IF &DBSYS = WDISAppendixH %then %do;
	%let dbsys = Appendix;
	%LET DIR=\\edw-fs02\CAE_Data\APPENDICES_WDIS_SECCTE\WDIS\H_appendixh_xls;
%end;

%ELSE %IF &DBSYS = WDISAppendixO %then %do;
	%let dbsys = Appendix;
	%LET DIR=\\edw-fs02\CAE_Data\APPENDICES_WDIS_SECCTE\WDIS\O_appendixo_xls;
%end;

%ELSE %IF &DBSYS = WDISAppendixP %then %do;
	%let dbsys = Appendix;
	%LET DIR=\\edw-fs02\CAE_Data\APPENDICES_WDIS_SECCTE\WDIS\P_appendixp_xls;
%end;

%ELSE %IF &DBSYS = WDISAppendixQ %then %do;
	%let dbsys = Appendix;
	%LET DIR=\\edw-fs02\CAE_Data\APPENDICES_WDIS_SECCTE\WDIS\Q_appendixq_xls;
%end;

%ELSE %IF &DBSYS = SECCTEWDISAppendixZ %then %do;
	%let dbsys = Appendix;
	%LET DIR=\\edw-fs02\CAE_Data\APPENDICES_WDIS_SECCTE\WDIS_SECCTE_AppendixZ_2324;
%end;

%ELSE %IF &DBSYS = BuildCIPSupportFiles %then %do;
	%let dbsys = Appendix;
	%LET DIR="\\edw-fs02\CAE_Data\CIPS\2023-2024\Build CIP and Support Files";
%end;

%ELSE %IF &DBSYS = 2324WDISReferenceTables %then %do;
	%let dbsys = Appendix;
	%LET DIR=\\edw-fs02\CAE_Data\CIPS\2023-2024\2324 WDIS REFERENCE TABLES;
%end;


/*%ELSE %IF &DBSYS = CBO2324SurveyReports %then %do;
	%let dbsys = CBO-2324-Survey-Reports-Programs;
	%LET DIR=\\edw-fs02\CAE_Data\CBO\CBO Survey Reports\2324;
%end;

%ELSE %IF &DBSYS = CBO2425SurveyReports %then %do;
	%let dbsys = CBO-2425-Survey-Reports-Programs;
	%LET DIR=\\edw-fs02\CAE_Data\CBO\CBO Survey Reports\2425;
%end;

%ELSE %IF &DBSYS = CBO2526SurveyReports %then %do;
	%let dbsys = CBO-2526-Survey-Reports-Programs;
	%LET DIR=\\edw-fs02\CAE_Data\CBO\CBO Survey Reports\2526;
%end;

%ELSE %IF &DBSYS = WDISPrograms2324 %then %do;
	%let dbsys = WDIS-2324;
	%LET DIR=\\edw-fs02\CAE_Data\WDIS\PRODUCTION\Survey Reports\2324;
%end;

%ELSE %IF &DBSYS = WDISPrograms2425 %then %do;
	%let dbsys = WDIS-2425;
	%LET DIR=\\edw-fs02\CAE_Data\WDIS\PRODUCTION\Survey Reports\2425;
%end;

%ELSE %IF &DBSYS = WDISprograms2526 %then %do;
	%let dbsys = WDIS-2526;
	%LET DIR=\\edw-fs02\CAE_Data\WDIS\PRODUCTION\Survey Reports\2526;
%end;*/
%ELSE %LET DIR=\\edw-fs02\CAE_Data\WDIS\PRODUCTION\Survey Reports\2324;

%PUT &DIR;
%MEND SETDIR;
%SETDIR;
RUN;
%MACRO SETOBS (DSET);

	DATA _NULL_;
		DSID=OPEN("&DSET");

		IF (DSID = 0) THEN DO;
			PUT 'FILE NOT OPENED';
		END;
		ELSE DO;
			PUT 'DSET DATA SET HAS BEEN OPENED';
			ISOBS=ATTRN(DSID,'NOBS');

			IF ISOBS GT -1 THEN DO;
				CALL SYMPUT ("FNOBS",RIGHT(PUT(ISOBS,8.)));
			END;
		END;
	RUN;
%MEND SETOBS;
%macro list_members;
	%global dnum;

	data tibco_list(KEEP=filename ext);
		format fref $char8. filename $char256. filetype $char100. CCNUM 8. CCNUMX $char2. colname $char50. sub $char1. trm 1. year $char4. dbtype $char3.
			ext $char3.;
		rc = filename(fref,"&DIR");

		if rc = 0 then
			do;
				did = dopen(fref);
				rc = filename(fref);
			end;
		else
			do;
				length msg $200.;
				msg = sysmsg();
				put msg=;
				did = .;
			end;

		if did <= 0 then
			putlog 'ERR' 'OR: Unable to open directory.';
		dnum = dnum(did);
		call symput("dnum",dnum);
		fcount = 0;
		%PUT &DNUM;

		do j = 1 to dnum;
			filename = dread(did, j);
			putlog filename=;
			fid = mopen(did, filename);
			ext=upcase(scan(filename,-1,'.'));
			NUMDOTS = count(filename,'.');
			putlog numdots=;

			IF ext IN ('SAS', 'egp') THEN
				output tibco_list;
		end;

		rc = dclose(did);
	run;

%mend list_members;

%list_members;
RUN;

%macro readraw;

	%SETOBS(tibco_list);

	DATA tibco_list;
	SET tibco_list NOBS=NOBS;
	RETAIN SEQ;
	SEQ=SUM(SEQ,1);
	RUN;

	%let rc=%sysfunc(filename(fileref,%superq(dir)));
	%let did=%sysfunc(dopen(&fileref));

	%do dmem=1 %to &fnobs;

	   	DATA _NULL_;
		SET tibco_list;
		WHERE SEQ = &dmem;
		CALL SYMPUT("memname",trim(filename));
		RUN;

		*--this is telling the code that we are only interested in files that have an extension of SAS;
		%if %qupcase(%qscan(%superq(memname),-1,.))=&ext. %then
			%do;
				*--depending on the file type you are looking at, you may need another method to read in the file contents;
				data temp;
					length program $3600.;
					infile "&dir.\&memname." truncover;
					input @01 line $char2500.;
					line_num=_n_;
					program="&dir\&memname.";

					if index(upcase(line), "&STRING") > 0 then
						do;
							line_num=_n_;
							program="&dir\&memname.";
							output;
						end;
				run;

				proc append data=temp base=all;
				run;

			%end;
	%end;

	%let dsid = %sysfunc(open(all));

	*-- If the data set exists, then grab the number of observations and variables;
	*-- then close the data seth;
	%if &dsid %then
		%do;
			%let nobs =%sysfunc(attrn(&dsid,nobs));
			%let rc = %sysfunc(close(&dsid));
			%put &nobs;

			%if &nobs > 0 %then
				%do;
					proc print data=all noobs;
						title "Looking for  &string.";
						title2 " &string found in the following programs";
					run;
				%end;
			%else %put NOTE: &string not found in &dir.;
		%end;

	%let didc=%sysfunc(dclose(%nrbquote(&did)));
	%let rc=%sysfunc(filename(fileref));
%mend readraw;

%readraw;
run;
2 REPLIES 2
SASJedi
SAS Super FREQ

For a head start, I have a ready-made macro (%findfiles) that can traverse directories and produce either a list of files with a specified extension in the log
or write them to a SAS dataset.
SYNTAX:
%FindFiles(dir,<ext,dsn,sub>)
   dir=fully qualified directory path
   ext=Space delimited list of file extensions (Optional, default is ALL)
   dsn=name of data set to store filenames (Optional, otherwise writes to log.)
   sub=look in subfolders? (Y|N default is Y)

Examples:
%FindFiles(c:\temp, csv)
%FindFiles(\\server\folder\, xls xlsx xlsm, work.myfiles)
%FindFiles(s:/workshop,sas,work.pgm_files,N)

This macro depends on three utility macros ( %exist, %fileattribs, and %translate). You can download the files from my GitHub sas-macros repository, or use this SAS code to download them:

%let path=<your custom macro storage location>;
filename maccode "&path/exists.sas";
proc http url="https://github.com/SASJedi/sas-macros/raw/master/exist.sas" out=maccode;
run;

filename maccode2 "&path/fileattribs.sas";
proc http url="https://github.com/SASJedi/sas-macros/raw/master/fileattribs.sas" out=maccode2;
run;

filename maccode3 "&path/translate.sas";
proc http url="https://github.com/SASJedi/sas-macros/raw/master/translate.sas" out=maccode3;
run;

filename maccode4 "&path/findfiles.sas";
proc http url="https://github.com/SASJedi/sas-macros/raw/master/findfiles.sas" out=maccode4;
run;

Examine the files you downloaded to see how the code works and to ensure there's nothing nefarious going on there, if you wish. 

/* After examining the code you downloaded, run the macro programs to compile the macors */
%include maccode;
%include maccode2;
%include maccode3;
%include maccode4;

filename maccode clear;
filename maccode2 clear;
filename maccode3 clear;
filename maccode4 clear;

/*Get syntax help in the log for any macro using ? as the only parameter value:*/
%findfiles(?)

You can then use the dataset you created to drive the rest of your process...

For example, I ran this on my computer:

%FindFiles(D:/Courses/PG1V2, xls xlsx xlsm, work.myfiles)
proc print noobs; run;

And this was the result:

Item Path Filename Size CRDate CRTime ModDate ModTime
1 D:/Courses/PG1V2/data class.xlsx 10,000 06/12/2023 7:51:04 12/08/2017 12:13:00
2 D:/Courses/PG1V2/data eu_sport_trade.xlsx 234,100 06/12/2023 7:51:04 12/19/2017 14:48:36
3 D:/Courses/PG1V2/data np_info.xlsx 7,234,320 06/12/2023 7:51:04 01/30/2018 13:26:40
4 D:/Courses/PG1V2/data storm.xlsx 6,859,276 06/12/2023 7:51:04 12/05/2019 12:51:42

Hope that helps.

Check out my Jedi SAS Tricks for SAS Users
ballardw
Super User

Which operating system?

 

DOS (and WIndows still supports Dos commands) FINDSTR

UNIX and derivative operating systems the GREP command does this

 

I would start with OS commands instead of writing from scratch as many of those are already set up to do directory and subdirectory searches.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 2 replies
  • 440 views
  • 2 likes
  • 3 in conversation