Solved

Find in Files (like Grep)

Posted on 2003-10-28
3
730 Views
Last Modified: 2012-05-04
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
0
Comment
Question by:Linking
[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
  • 2
3 Comments
 
LVL 6

Expert Comment

by:swift99
ID: 9638664
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
 
LVL 2

Accepted Solution

by:
alsantos earned 500 total points
ID: 9638823
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
 
LVL 6

Expert Comment

by:swift99
ID: 9639061
If you open the files for read shared then you should be good for most files, unless they are opened for exclusive use.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses
Course of the Month5 days, 13 hours left to enroll

626 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