search_file, a simple text search utility



The function search_file builds on the string
tools recently created in writing text_replace.

The simplest two arg form only returns line numbers
and line text if the substring appears as a distinct
word (as defined by sword).
------------------------------------------------
(%i1) display2d:false$
(%i2) load(mtext);
(%o2) "c:/work2/mtext.mac"

(%i3) printfile("text1.txt")$
is this line one? Yes, this is line one.
This might be line two.
Here is line three.
I insist that this be line four.
This is line five, isn't it?

(%i4) search_file ("text1.txt","is");
 1  is this line one? Yes, this is line one.
 3  Here is line three.
 5  This is line five, isn't it?
(%o4) done

(%i5) search_file ("text1.txt","is",word)$
 1  is this line one? Yes, this is line one.
 3  Here is line three.
 5  This is line five, isn't it?

(%i6) search_file ("text1.txt","is",all)$
 1  is this line one? Yes, this is line one.
 2  This might be line two.
 3  Here is line three.
 4  I insist that this be line four.
 5  This is line five, isn't it?
-------------------------------------
The code for search_file is:
------------------------------
search_file ([%u]) :=

    block ([%fname,%ss,%tmode : word,%lines,%flines:[],%ls,%nl:0,%p],

      %fname : part (%u,1),

      if not stringp (%fname)
         then ( disp (" file name must be a Maxima string "),
              return (false)),

      if not file_search (%fname) then
         (disp (" file not found "),return (false)),

      %ss : part (%u,2),
      if not stringp (%ss) then (
        disp (" second arg must be a string "),
        return (false)),

      if length (%u) > 2 then
        %tmode : part (%u,3),

      %lines : read_text (%fname),
      if not %lines then return (false),
      if length (%lines) = 0 then return(false),

      for %ls in %lines do
       (%nl : %nl + 1,
       if slength (%ls) # 0 then
          ( if %tmode = word then
               %nfirst : wsearch(%ss,%ls)
              else  %nfirst : ssearch(%ss,%ls),
            if integerp (%nfirst) then %flines : cons ([%nl,%ls],%flines))),

      %flines : reverse (%flines),

      if length (%flines) = 0 then return (false),

      for %p in %flines do
        printf(true," ~d  ~a ~%",part (%p,1),part (%p,2)))$
----------------------------------------
search_file first uses read_text, whose code is:
--------------------------------------------------
  /**************** read_text *******************************/
  /*  read_text(filename) preserves blank lines in the source
     file, and reads in each line as a string,
     returns a list of strings, one for each physical
     line in the source file. */

  read_text(%filename) :=
     block ([%s,%r:[],%l ],

      if not stringp (%filename)
         then ( disp (" file name must be a Maxima string "),
              return (false)),

      if not file_search (%filename) then
         (disp (" file not found "),return (false)),

      %s : openr (%filename),

      while (%l : readline(%s)) # false do
          %r : cons (%l,%r),

      close(%s),

      reverse (%r))$
    ---------------------------

When looking for lines with distinct words,
search_file uses wsearch (which calls sword):
-----------------------------------------------------
   /************ wsearch ******************/

   wsearch(%substr,%string) :=
               sword (%string,%substr,1)$


  /*
  (%i10) load(mtext);
(%o10) "c:/work2/mtext.mac"
(%i11) ss : openr("text1.txt");
(%o11) ?\#\<input\ stream\ text1\.txt\>
(%i12) ls : readline(ss);
(%o12) "is this line one? Yes, this is line one."
(%i13) wsearch("is",ls);
(%o13) 1
(%i14) ls : readline(ss);
(%o14) "This might be line two."
(%i15) wsearch("is",ls);
(%o15) false
(%i16) ls : readline(ss);
(%o16) "Here is line three."
(%i17) wsearch("is",ls);
(%o17) 6
(%i18) ls : readline(ss);
(%o18) "I insist that this be line four."
(%i19) wsearch("is",ls);
(%o19) false
(%i20) ls : readline(ss);
(%o20) "This is line five, isn't it?"
(%i21) wsearch("is",ls);
(%o21) 6
(%i22) close(ss);
(%o22) true
*/

--------------------------
Ted Woollett