- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.