Subject: search_file, a simple text search utility
From: Edwin Woollett
Date: Sat, 4 Jun 2011 13:48:21 -0700
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