Over time we tend to collect a large number of program files.  It never fails that after much time has past that you need to access some code in a file but can't recall which program the keyword was in.
I work on a Linux operating system so I can use the GREP command to handle the task but I never remember the syntax options and do not like the way the data is returned.  That is why I wrote a macro named %findtext() that handles this for you in SAS via the use of a PIPE command.
If want to work for the keyword 'bitwise' in all SAS programs in a folder and any sub-folders that GREP command will be as follows:
> grep -nRi 'updatestagingdetails' '/em_data1/prod/macro' --include=*.sas
/em_data1/prod/macro/etl.sas:524:       %updatestagingdetails(env_out=&env_out.);
/em_data1/prod/macro/updatestagingdetails.sas:2:*     Program: updatestagingdetails.sas
/em_data1/prod/macro/updatestagingdetails.sas:9:*       Usage: %updatestagingdetails(dsn=work.stagingdetails,env_out=%env())
/em_data1/prod/macro/updatestagingdetails.sas:21:%macro updatestagingdetails( dsn  = work.stagingdetails, env_out = %env() ) ;
/em_data1/prod/macro/updatestagingdetails.sas:40:/*EOF: updatestagingdetails.sas */
Notice in the above output that the values are separated by a colon (:) and it is overall hard to read in my opinion.  This is where the SAS SCAN and FIND functions come into play to create a cleaner easier to read result.
The SAS macro call will be as follows (only the first two parameters are required):
%findtext(
  path      = /em_data1/prod/macro
 , text     = updatestagingdetails 
  , ignorecase   = Y
  , exactmatch   = N
  , extension    = sas
  , outdsn       = findtextresults
  , printresults = Y
);
 
/*******************************************************************************
     Program: findtext.sas
      Author: Tom Bellmer
Responsible: Tom Bellmer
     Created: 08/10/2020 @ 3:00:45 PM
SAS Version: SAS 9.4 (TS1M6)
          OS: LIN X64
     Purpose: read the contents of files searching for the string value
       Usage: %findtext(path = /folder, string = sql);
       Notes: colon is used as output separator.  Scan() function had issues
              with third column that contained colons.
  Parameters: path = (folder path to be searched)
              text = (text to be searched inside each file)
              ignorecase = Y/N to ignore the case of the &string.
              exactmatch = N/Y to match whole &string value
              extension = sas (file extension, use * for all files)
              outdsn = findtextresults (output data set name)
              printresults = Y (proc print the results? Y/N)
 
                             Modifications in descending order
FL-YYYYMMDD                             Description
----------- --------------------------------------------------------------------
 
         1    1    2    2    3    3    4    4    5    5    6    6    7    7    8
....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
*******************************************************************************/
 
%macro findtext(
    path         =
  , text         =
  , ignorecase   = Y
  , exactmatch   = N
  , extension    = sas
  , outdsn       = findtextresults
  , printresults = Y
);
 
  %local options i;
  %do i = 1 %to 100;
    %local pathname&i;
  %end;
 
  %if %isblank(&path) %then %do;
    %put %str(E)RROR: Must pass in a value for path.;
    %return;
  %end;
 
  %if %isblank(&text) %then %do;
    %put %str(E)RROR: Must pass in a value for text.;
    %return;
  %end;
 
  /*   i = ignores case, n = show matched line number
     , R = recursively,  w = match whole word  */
  %let options = -nR;
  %if %upcase(&ignorecase) = Y %then %let options = &options.i;
  %if %upcase(&exactmatch) = Y %then %let options = &options.w;
 
  filename search pipe "grep &options '&text' '&path' --include='*.&extension'";
  data &outdsn(drop = fullfilename findpos);
    attrib
      Path         length = $256 label = 'Path'
      Filename     length = $128 label = 'Filename'
      Lineno       length = 8    label = 'Line No'
      Code         length = $256 label = 'Code'
      Fullfilename length = $256 label = 'Full Filename'
    ;
 
    infile search;
    input;
    fullfilename = scan(_infile_, 1, ':');
    filename     = scan(fullfilename, -1, "/");
    path         = substr(_infile_, 1, lengthn(fullfilename) - lengthn(filename));
    lineno       = input(scan(_infile_, 2, ':'), 8.);
    findpos      = find(_infile_, ":");
    findpos      = find(_infile_, ":", findpos + 1);
    code         = substr(_infile_, findpos + 1);
  run;
  filename search clear;
 
  %if %getattr(dsn = &outdsn, attr = nlobs) = 0 %then %do;
    proc sql;
      insert into &outdsn
        set path     = "&path"
          , filename = "N/A"
          , lineno   = 0
          , code     = "No results were found using '&text'"
      ;
    quit;
  %end;
 
  %if %upcase(%substr(&printresults, 1, 1)) = Y %then %do;
    proc sql noprint;
      select   distinct path
      into     :pathname1 -
      from     &outdsn;
    quit;
   
    title "Search results for: &text";
    %if &sqlobs = 1 %then %do;
      title2 "In Path: &pathname1";
    %end;
    proc print data = &outdsn;
      %if &sqlobs = 1 %then %do;
         var filename lineno code;
      %end;
    run;
    title;
  %end;
%mend;
 
/*EOF: findtext.sas */