Find in Files (like Grep)

I need to be able to search through files (a mixture of Word, Powerpoint,PDF,Databases,Applications ) raplidly for a given string- similar to the Unix grep process. The files may contain just system code as well.

Has anyone any code to do this please, I will need to cope with files that may be open as well

Thanks
LVL 1
LinkingAsked:
Who is Participating?
 
alsantosConnect With a Mentor Commented:
Hi Linking, You can use this code, It will search for a string in all files in directory(and subdirectory) you want and put at listbox the files that have the text in.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    ListBox1: TListBox;
    Button2: TButton;
    Edit3: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    FScanAborted: Boolean;
  public
    Function ScanDrive( root, filemask: String; Text2Find: String; hitlist: TStrings ): Boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TextExist(FileName: String;String2Find: String): Boolean;
Var
  MyStream: TMemoryStream;
  MyString: String;
  A: Integer;
begin
  Result := False;
  MyStream := TMemoryStream.Create;
  Try
    MyStream.LoadFromFile(FileName);
    SetLength(MyString, MyStream.Size);
    MyStream.ReadBuffer(Pointer(MyString)^,MyStream.Size);
    A := Pos(String2Find,MyString);
    If A <> 0 then
        Result:=True;
    Finally
     MyStream.Free;
    end;
end;

Function TForm1.ScanDrive( root, filemask: String; Text2Find: String; hitlist: TStrings ): Boolean;
  Function ScanDirectory( Var path: String ): Boolean;
    Var
      SRec: TSearchRec;
      pathlen: Integer;
      res: Integer;
    Begin
      label1.caption := path;
      pathlen:= Length(path);
      res := FindFirst( path+filemask, faAnyfile, SRec );
      If res = 0 Then
      try
        While res = 0 Do
         Begin
          if FileExists(path + SRec.Name) then
            if TextExist(path + SRec.Name, Text2Find) then
               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;
 
      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
  Screen.Cursor := crHourglass;
  try
    Result := ScanDirectory(root);
  finally
    Screen.Cursor := crDefault
  end;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
  listbox1.clear;
  ScanDrive(edit1.text, edit2.text, edit3.text, listbox1.items );
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 fScanAborted := True;
end;

end.

alsantos :)
0
 
swift99Commented:
grep is actually shipped with Delphi   :o)

It is also an open source utility, so you should be able to lift the code you need directly from it so long as you adhere to the license agreement.

Worst case scenario, you just need to use the directory reading functions to traverse the directories.

see SearchRec, FindFirst, FindNext, and FindClose functions in the Delphi online help.  The example provided there should get you started.

For every file, you open the file as a file of char, and then you read through it one character at a time looking for a match to the characters you are looking for.

As you do this, several obvious optimizations will probably occur to you.
0
 
swift99Commented:
If you open the files for read shared then you should be good for most files, unless they are opened for exclusive use.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.