I have too Many SAS codes in more than three Directories. How do I search for a Specific text in Side the SAS codes.
For instance: I want to search FNAME,LNAME in All my SAS codes.
thanks
I made a variant based on @Patrick's code:
You may change SUFFIX to LOG, TXT, or any other one.
You can add more directories in filename path.
Result is given in sas dataset, including:
- fname = path and file name
- a_line = line that contains the string
_n = line nomber withein the input file
%let search_string = libname;
%let suffix = sas;
%let root=/folders/myshortcuts/My_Folders/;
filename finp ("&root.source/*.&suffix");
data results;
length fname _filepath $200;
infile finp filename = _filepath eov=_eov truncover;
input a_line $200.;
fname = _filepath;
if _eov=1 then do;
_n=0;
_eov=0;
end;
_n+1;
if find(a_line,"&search_string",'i')
then output;
keep _n a_line fname;
run;
In Windows, I use the Windows Explorer search or the multi file searching feature in Notepad++.
One way to go:
%let search_string=libname;
filename sascode ('c:\temp\*.sas' 'c:\test\*.sas');
data _null_;
file print;
length _filepath $200;
retain _found_flg 0;
infile sascode filename=_filepath eov=_eov;
input;
if _eov=1 then
do;
_n=0;
_found_flg=0;
_eov=0;
end;
_n+1;
if find(_infile_,"&search_string",'i') then
do;
if _found_flg=0 then
do;
put / 'File is: ' _filepath;
_found_flg=1;
end;
put @1 _n z4. @5 _infile_;
end;
run;
Patrick,
I like your approach it is easy to understand. Is there away i can create the unique files name from all the directories.
something like this one.
FileNAME | search_string |
c:\desktop\X1.SAS | Fname |
c:\document\X2.SAS | Fname |
c:\desktop\file\X3.SAS | Fname |
|
|
Thanks,
I made a variant based on @Patrick's code:
You may change SUFFIX to LOG, TXT, or any other one.
You can add more directories in filename path.
Result is given in sas dataset, including:
- fname = path and file name
- a_line = line that contains the string
_n = line nomber withein the input file
%let search_string = libname;
%let suffix = sas;
%let root=/folders/myshortcuts/My_Folders/;
filename finp ("&root.source/*.&suffix");
data results;
length fname _filepath $200;
infile finp filename = _filepath eov=_eov truncover;
input a_line $200.;
fname = _filepath;
if _eov=1 then do;
_n=0;
_eov=0;
end;
_n+1;
if find(a_line,"&search_string",'i')
then output;
keep _n a_line fname;
run;
Dear Shmuel;
Is there a way we can search for more than one text.
Like if i want to search "FNAME" or "LNAME" or "MNAME" at the same time
thanks
A fast, non efficient way is to do:
search for string-1, copy results to results-1
search for string-2, copy results to results-2
search for string-3
merge all results by: fname, _n
To give you a better and more efficient way (one thread), I'll try to convert the
code into a macro - next week.
happy new year 2017.
More efficient way, without mcaro programing, just add as many as you want search_strings:
%let search_string_1 = lname;
%let search_string_2 = fname;
%let search_string_3= mname;
%let suffix = sas;
%let root=/folders/myshortcuts/My_Folders/;
filename finp ("&root.source/*.&suffix");
data results;
length fname _filepath $200;
infile finp filename = _filepath eov=_eov truncover;
input a_line $200.;
fname = _filepath;
if _eov=1 then do;
_n=0;
_eov=0;
end;
_n+1;
if find(a_line,"&search_string_1",'i')
or find(a_line,"&search_string_2",'i')
or find(a_line,"&search_string_3",'i')
then output;
keep _n a_line fname;
run;
In unix or linux xterminal you can do:
cat *.sas | grep any_string > lising.txt
where: cut + grep functions scan all sas programs for "any_string"
when found line is written to file "listing.txt"
It is possible to do it by sas program using functions: filename, dopen, dread, fopen, fread, close;
Would you like to struggle it yourself ? It may take quite a time to write it and debug it.
here is an example of exploring one directory. (try expanding it to search a string )
%let path = ...;
filename mydir "&path";
data dir_info;
length fname $40 type $12 ;
did = dopen('mydir');
members = dnum(did); /* nomber of files in directory */
if did then
do 1 to members;
fname = dread(did,i);
if indexc(fname,'.') = 0 then type='directory';
else type='file';
output;
/* if type = file: open it and scan each line for the string */
/* using similar functions: fopen, fread, index, close */
end;
did = close(did)
keep i fname type;
run;
c
You can try the below code to first read all the contents of the directory:
this will read the content of each file row by row and check the contents of the file and match it against the keywords you want and then it will output.
Along with the full record, you will also get the actual file path of the file and the record number in the file, so that you always know where that record came from.
Cheer!
filename INP "c:\users\xxxxx\desktop\*.sas";
DATA SRC;
;
LENGTH _filepath FILEPATH1 $550;
INFILE INP filename = _filepath LRECL=80 PAD END = DONE ;
DO WHILE(NOT DONE);
INPUT REC $CHAR80.;
filepath1 = STRIP(_filepath);
RECNO+1;
IF INDEX(UPCASE(REC),'FILENAME') THEN OUTPUT;
END;
RUN;
Dear mnjtrana;
I tried your code and managed to call all the SAS codes in my directories:
Thanks
Hi @tekish
In my code below, you can use the statement and replace the 'FILENAME' statement to whatever you want to search in your code.
See the undelined.
filename INP "c:\users\xxxxx\desktop\*.sas";
DATA SRC;
;
LENGTH _filepath FILEPATH1 $550;
INFILE INP filename = _filepath LRECL=80 PAD END = DONE ;
DO WHILE(NOT DONE);
INPUT REC $CHAR80.;
filepath1 = STRIP(_filepath);
RECNO+1;
IF INDEX(UPCASE(REC),'FILENAME') THEN OUTPUT;
END;
RUN;
Let me know, if that helps!
Manjeet
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.