Solved

Search in files

Posted on 2000-04-02
6
174 Views
Last Modified: 2010-04-04
How can I search a string in the list of text files?

Thanks
0
Comment
Question by:shtern
  • 4
6 Comments
 
LVL 17

Accepted Solution

by:
inthe earned 50 total points
Comment Utility
hi,
use the pos function like below:

procedure TForm1.Button2Click(Sender: TObject);
begin
if pos('boo',edit1.text)<>0 then showmessage('textfound')else showmessage('no found');
end;


0
 
LVL 17

Expert Comment

by:inthe
Comment Utility
or you could use a tfinddialog fo text in a richedit:

procedure TForm1.Button1Click(Sender: TObject);
begin
FindDialog1.Execute;
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
var
  FoundAt: LongInt;
begin
  with RichEdit1 do  begin
    FoundAt := Pos(FindDialog1.FindText, Text) - 1;
    if (FoundAt <> 0) then
    begin
      SetFocus;
      SelStart := FoundAt;
      SelLength := Length(FindDialog1.FindText);
      SelAttributes.Color:=clred;
      SelAttributes.style := [fsbold];
      clearselection;
    end;
  end;
end;
0
 
LVL 17

Expert Comment

by:inthe
Comment Utility
or you could use a tfinddialog fo text in a richedit:

procedure TForm1.Button1Click(Sender: TObject);
begin
FindDialog1.Execute;
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
var
  FoundAt: LongInt;
begin
  with RichEdit1 do  begin
    FoundAt := Pos(FindDialog1.FindText, Text) - 1;
    if (FoundAt <> 0) then
    begin
      SetFocus;
      SelStart := FoundAt;
      SelLength := Length(FindDialog1.FindText);
      SelAttributes.Color:=clred;
      SelAttributes.style := [fsbold];
      clearselection;
    end;
  end;
end;
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:shtern
Comment Utility
Hi, inthe,
sorry, I don't understand. As it stays in Delphi help, pos function finds just a substring in a string. Your second comment is nearer, but I need to search in  a lot of files (not in one which I can load in Richedit), e.g.  find files in a directory which contain my string, not in filename, but in contents.
0
 
LVL 17

Expert Comment

by:inthe
Comment Utility
ok ,
i had a quick look and found this,i havent time to test till tommorrow ,
but it will help you on your way for now,hope its more what you were after.

<start paste>

there are two tasks here: scanning the disk(s) for files with a set of extensions and scanning each file found for the phrase. In short, you want a Grep utility <g>. I'm sure you could find something on the usual Delphi websites ,dsp for instance:
http://sunsite.icm.edu.pl/delphi/
using GREP as search word.
 
Anyway, part 1 is a recursive FindFirst/FindNext loop. Here is a sample for that, which you will have to adapt to integrate the search for a phrase:
 
recursively scanning all drives
 
  { excerpt from form declaration, form has a listbox1 for the
    results, a label1 for progress, a button2 to start the scan,     an edit1 to get the search mask from, a button3 to stop
    the scan. }
  private
    { Private declarations }
    FScanAborted: Boolean;
 
  public
    { Public declarations }
    Function ScanDrive( root, filemask: String; hitlist: TStrings ): Boolean;
 
 
Function TForm1.ScanDrive( root, filemask: String; hitlist: TStrings ): Boolean;
  Function ScanDirectory( Var path: String ): Boolean;
    Var
      SRec: TSearchRec;
      pathlen: Integer;
      res: Integer;
    Begin
      label1.caption := path;
      pathlen:= Length(path);
      { first pass, files }
      res := FindFirst( path+filemask, faAnyfile, SRec );
      If res = 0 Then
      try
        While res = 0 Do Begin
          hitlist.Add( path + SRec.Name );
          res := FindNext(SRec);
        End;
      finally
        FindClose(SRec)
      end;
      Application.ProcessMessages;
      Result := not (FScanAborted or Application.Terminated);
      If not Result Then Exit;
 
      {second pass, directories}
      res := FindFirst( path+'*.*', faDirectory, SRec );
      If res = 0 Then
      try
        While (res = 0) and Result Do Begin
          If ((Srec.Attr and faDirectory) = faDirectory) and
            (Srec.name[1] <> '.')
          Then Begin
            path := path + SRec.name + '\';
            Result := ScanDirectory( path );
            SetLength( path, pathlen );
          End;
          res := FindNext(SRec);
        End;
      finally
        FindClose(SRec)
      end;
    End;
Begin
  FScanAborted := False;
  Screen.Cursor := crHourglass;
  try
    Result := ScanDirectory(root);
  finally
    Screen.Cursor := crDefault
  end;
End;
 
procedure TForm1.Button2Click(Sender: TObject);
Var
  ch: Char;
  root: String;
Begin
  root := 'C:\';
  For ch := 'A' to 'Z' Do Begin
    root[1] := ch;
    Case GetDriveType( Pchar( root )) Of
      DRIVE_FIXED, DRIVE_REMOTE:
        If not ScanDrive( root, edit1.text, listbox1.items ) Then           Break;
    End;
  End;
end;
 
procedure TForm1.Button3Click(Sender: TObject);
begin // aborts scan
  fScanAborted := True;
end;
 
And as a bonus here is a function to search a file for a string:
 
Function ScanFile( Const filename: String;
                    Const forString: String;
                    caseSensitive: Boolean ): LongInt;
{ returns position of string in file or -1, if not found }
Const
  BufferSize= $8001;  { 32K+1 bytes }
Var
  pBuf, pEnd, pScan, pPos : Pchar;
  filesize: LongInt;
  bytesRemaining: LongInt;
  bytesToRead: Word;
  F    : File;
  SearchFor: Pchar;
  oldMode: Word;
Begin
  Result := -1;  { assume failure }
  If (Length( forString ) = 0) or (Length( filename ) = 0) Then Exit;   SearchFor := Nil;
  pBuf      := Nil;
 
  { open file as binary, 1 byte recordsize }
  AssignFile( F, filename );
  oldMode := FileMode;
  FileMode := 0;    { read-only access }
  Reset( F, 1 );
  FileMode := oldMode;
  try { allocate memory for buffer and pchar search string }
    SearchFor := StrAlloc( Length( forString )+1 );
    StrPCopy( SearchFor, forString );
    If not caseSensitive Then  { convert to upper case }
      AnsiUpper( SearchFor );
    GetMem( pBuf, BufferSize );
    filesize := System.Filesize( F );
    bytesRemaining := filesize;
    pPos := Nil;
    While bytesRemaining > 0 Do Begin
      { calc how many bytes to read this round }
      If bytesRemaining >= BufferSize Then
        bytesToRead := Pred( BufferSize )
      Else
        bytesToRead := bytesRemaining;
 
      { read a buffer full and zero-terminate the buffer }
      BlockRead( F, pBuf^, bytesToRead, bytesToRead );
      pEnd := @pBuf[ bytesToRead ];
      pEnd^:= #0;
      { scan the buffer. Problem: buffer may contain #0 chars! So we         treat it as a concatenation of zero-terminated strings. }       pScan := pBuf;
      While pScan < pEnd Do Begin
        If not caseSensitive Then { convert to upper case }
          AnsiUpper( pScan );
        pPos := StrPos( pScan, SearchFor );  { search for substring }         If pPos <> Nil Then Begin { Found it! }
          Result := FileSize - bytesRemaining +
                    LongInt( pPos ) - LongInt( pBuf );
          Break;
        End;
        pScan := StrEnd( pScan );
        Inc( pScan );
      End;
      If pPos <> Nil Then Break;
      bytesRemaining := bytesRemaining - bytesToRead;
      If bytesRemaining > 0 Then Begin
      { no luck in this buffers load. We need to handle the case of         the search string spanning two chunks of file now. We simply         go back a bit in the file and read from there, thus inspecting         some characters twice
      }
        Seek( F, FilePos(F)-Length( forString ));
        bytesRemaining := bytesRemaining + Length( forString );       End;
    End; { While }
  finally
    CloseFile( F );
    If SearchFor <> Nil Then StrDispose( SearchFor );
    If pBuf <> Nil Then FreeMem( pBuf, BufferSize );
  end;
end; { ScanFile }
0
 
LVL 9

Expert Comment

by:ITugay
Comment Utility
Sample bellow is shown how to find substring in list of texts files.

legend:
(TEdit)  Edit1.Text - string to search
(TListBox) ListBox1 - list of files to search
(TListBox) ListBox2 - result of search, if string found then filename + position of string in text file will there.

-----------------
function SearchInFile(aFileName,aSearchStr : string) : integer;
var L : TStringList;
begin
  result:=0;
  L:=TStringList.Create;
  try
    L.LoadFromFile(aFileName);
    result:=pos(aSearchStr,L.Text);
  finally
    L.Free;
  end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
var I,N : integer;
begin
   ListBox2.Clear; // clear result
   for I:=0 to ListBox1.Items.Count-1 do // iterate all files
   begin
     N:=SearchInFile(ListBox1.Items[I],Edit1.Text); // search
     if N > 0 // put result
        then ListBox2.Items.Add(ListBox1.Items[I]+' '+IntToStr(N-1));
   end;
end;
--------

Cheers,
Igor
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now