?
Solved

Search in files

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

Thanks
0
Comment
Question by:shtern
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
6 Comments
 
LVL 17

Accepted Solution

by:
inthe earned 200 total points
ID: 2678204
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
ID: 2678207
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
ID: 2678210
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:shtern
ID: 2678244
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
ID: 2678465
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
ID: 2680170
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses
Course of the Month13 days, 4 hours left to enroll

777 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