Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 187
  • Last Modified:

Search in files

How can I search a string in the list of text files?

Thanks
0
shtern
Asked:
shtern
  • 4
1 Solution
 
intheCommented:
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
 
intheCommented:
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
 
intheCommented:
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
shternAuthor Commented:
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
 
intheCommented:
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
 
ITugayCommented:
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: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

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.

  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now