Solved

Search/Replace

Posted on 2004-03-25
10
306 Views
Last Modified: 2010-04-05
Dear friends,

My question is older than running...
I would need your help for writing a script for searching and replace a phrase,
for example, in all files .txt in all disks available on the computer.

Best regards,

Dict
0
Comment
Question by:dict
  • 3
  • 3
  • 3
  • +1
10 Comments
 
LVL 17

Expert Comment

by:mokule
ID: 10683031
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 10686133
Hi,

Right from the RX-Lib StrUtils-Unit :

function ReplaceStr(const S, Srch, Replace: string): string;
var
  I: Integer;
  Source: string;
begin
  Source := S;
  Result := '';
  repeat
    I := Pos(Srch, Source);
    if I > 0 then begin
      Result := Result + Copy(Source, 1, I - 1) + Replace;
      Source := Copy(Source, I + Length(Srch), MaxInt);
    end
    else Result := Result + Source;
  until I <= 0;
end;

Used in a little application (with a TMemo, 2 TEdits and a TButton) :
When clicked on Button, in the content of the TMemo the text in first TEdit is replaced by the trext in the second one.

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Text := ReplaceStr( Memo1.Text, Edit1.Text, Edit2.Text);
end;
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 10686195
Hi,

I just made a little demo-application to make use of my previous mentioned function (RX-Lib)
Just put a TButton and 4 TEdits on your form.
Call them :
    Button1: TButton;
    edtPath: TEdit;
    edtFileMask: TEdit;
    edtSearch: TEdit;
    edtRepace: TEdit;


This is a copy of my complete unit.
Just try it out and let me know if this is what you are looking for.


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    edtPath: TEdit;
    edtFileMask: TEdit;
    edtSearch: TEdit;
    edtRepace: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure ReplaceTextInFiles( Path, Mask, Search, Replace : String );
    function  ReplaceStr(const S, Srch, Replace: string): string;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

Uses FileCtrl;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ReplaceTextInFiles(edtPath.Text, edtFileMask.Text, edtSearch.Text, edtRepace.Text );
end;


procedure TForm1.ReplaceTextInFiles(Path, Mask, Search, Replace: String);
var
  sr        : TSearchRec;
  fileAttrs : Integer;
  tstrTmp   : TStringList;
begin
  Try
    fileAttrs := faAnyFile; { parameter to get any file of any type. }
    if not DirectoryExists( Path ) then
      MessageDlg('Directory does not exist : ' + Path, mtError, [mbOK], 0)
    else
    begin
      if not FindFirst( IncludeTrailingBackSlash( Path ) + Mask, fileAttrs, sr ) = 0 then
        MessageDlg('No files found with following mask : ' + Mask, mtError, [mbOK], 0)
      else
      begin
        tstrTmp := TStringList.Create; { to hold the content of the current file }
        Repeat
          tstrTmp.LoadFromFile( sr.Name ); { Load File }
          tstrTmp.Text := ReplaceStr( tstrTmp.Text, Search, Replace ); { do replacements }
          tstrTmp.SavetoFile( sr.Name ); { Save file wit hchanges. }
        until FindNext( sr ) <> 0;
        FindClose( sr );
        FreeAndNil(tstrTmp);
      end;
    end;
  except
    MessageDlg('Something went wrong in replacing the text in the files.', mtError, [mbOK], 0);
  end; { Try Except }
end;

function TForm1.ReplaceStr(const S, Srch, Replace: string): string;
var
  I: Integer;
  Source: string;
begin
  Source := S;
  Result := '';
  repeat
    I := Pos(Srch, Source);
    if I > 0 then begin
      Result := Result + Copy(Source, 1, I - 1) + Replace;
      Source := Copy(Source, I + Length(Srch), MaxInt);
    end
    else Result := Result + Source;
  until I <= 0;
end;

end.




I compiled it with no errors, but have not tested it.
Best regards,

The Mayor.
0
Three Reasons Why Backup is Strategic

Backup is strategic to your business because your data is strategic to your business. Without backup, your business will fail. This white paper explains why it is vital for you to design and immediately execute a backup strategy to protect 100 percent of your data.

 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 10686208
Found a little bu in my repaut-loop.
It should be :


        Repeat
          tstrTmp.LoadFromFile( IncludeTrailingBackSlash( Path ) +  sr.Name ); { Load File }
          tstrTmp.Text := ReplaceStr( tstrTmp.Text, Search, Replace ); { do replacements }
          tstrTmp.SavetoFile( IncludeTrailingBackSlash( Path ) + sr.Name ); { Save file wit hchanges. }
        until FindNext( sr ) <> 0;
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 10686521
Download from:
http://www.geocities.com/esoftbg/
file:
Q_20932619.zip
It contains: Q_20932619.exe and Q_20932619.txt
Copy Q_20932619.txt into many different folders in all your HDD's
and then start Q_20932619.exe
If you like the exe I'll provide you the source code.

emil
0
 

Author Comment

by:dict
ID: 10695938
Dear wimmeyvaert,

I tested your script with success! Thank you very much.

However, your script scan (search/replace) only the files of a directory or disk, not all.

Regards,

Dict
0
 

Author Comment

by:dict
ID: 10695972
Dear  esoftbg,

I testes your program with success! Q_20932619.zip

You did a program very useful, congratulations for your ability as programmer!

I am asking by email ´lebronletchev´ the source code.

Thank you

Dict
0
 
LVL 12

Accepted Solution

by:
esoftbg earned 100 total points
ID: 10696322
I will post here the source code, because I don't understand ´lebronletchev´ as e-mail address. If you post a real e-mail, I'll send the full code on it.

unit Unit_Q_20932619;
// I love Borland Delphi so much
interface

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

type
  TForm_Q_20932619 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    CheckListBox1: TCheckListBox;
    CheckBox1: TCheckBox;
    Label1: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    Label2: TLabel;
    Label3: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
  private   { Private declarations }
    procedure Replace_Text(FName, OldText, NewText: string);
    procedure Replace_File(PathName: string; SL: TStringList);
  public    { Public declarations }
  end;

var
  Form_Q_20932619: TForm_Q_20932619;

implementation

{$R *.dfm}

procedure TForm_Q_20932619.FormCreate(Sender: TObject);
begin
  CheckListBox1.Checked[0] := True;
end;

function  Load_From_File(FName: string; StrList: TStringList): Boolean;
var
  B:      Boolean;
begin
  B := True;
  try
    try
      StrList.LoadFromFile(FName);
    except
      B := False;
    end;
  finally
    Result := B;
  end;
end;

procedure TForm_Q_20932619.Replace_Text(FName, OldText, NewText: string);
var
  B:      Boolean;
  I:      Integer;
  L:      Integer;
  P:      Integer;
  StrList:TStringList;
  S:      string;
  T:      string;
  R:      string;
begin
  StrList := TStringList.Create;
  B := False;
  try
    L := Length(OldText);
    if Load_From_File(FName, StrList) then
    for I := 0 to StrList.Count-1 do
    begin
      S := StrList.Strings[I];
      P := Pos(OldText, S);
      if (P>0) then
      begin
        T := Copy(S, 1, P-1);
        R := Copy(S, P+L, Length(S)-P-L+1);
        S := T + NewText + R;
        StrList.Strings[I] := S;
        B := True;
      end;
    end;
  finally
    if B then
    begin
      StrList.SaveToFile(FName);
      ListBox1.Items.Add(FName);
      Application.ProcessMessages;
    end;
    StrList.Destroy;
  end;
end;

procedure TForm_Q_20932619.Replace_File(PathName: string; SL: TStringList);
var
  Found:         Integer;
  Attr:          Integer;
  I:             Integer;
//  P:             Integer;
  S:             string;
  T:             string;
  FName:         string;
  DirName:       string;
  SearchRec:     TSearchRec;
  procedure Prepare_For_Replace(Name: string);
  begin
    if ((FileGetAttr(Name) and faReadOnly) > 0) then
      FileSetAttr(Name, FileGetAttr(Name) xor faReadOnly);
    if ((FileGetAttr(Name) and faHidden) > 0) then
      FileSetAttr(Name, FileGetAttr(Name) xor faHidden);
    if ((FileGetAttr(Name) and faSysFile) > 0) then
      FileSetAttr(Name, FileGetAttr(Name) xor faSysFile);
  end;
begin
  Attr := faDirectory;
  Found := FindFirst(PathName+'*.*', Attr, SearchRec);
  while (Found=0) do
  try
    if (((FileGetAttr(SearchRec.Name) and faArchive) > 0)
    or  ((FileGetAttr(SearchRec.Name) and faAnyFile) > 0)) then
    for I := 0 to SL.Count-1 do
    begin
      FName := PathName + SearchRec.Name; // SL.Strings[I];
      if FileExists(FName) then
      begin
        Prepare_For_Replace(FName);
        S := UpperCase(ExtractFileExt(FName));
        T := UpperCase(SL.Strings[I]);
        {
        P := Pos('.', T);
        Delete(T, 1, P-1);
        }
        T := UpperCase(ExtractFileExt(T));
        if (S=T) then
        begin
          Prepare_For_Replace(FName);
          // Here to be a replacement
          if (Edit1.Text<>'') then
            Replace_Text(FName, Edit1.Text, Edit2.Text);
        end;
      end;
    end;
    if ((SearchRec.Attr=2064) or (SearchRec.Attr=16))
    and (not (SearchRec.Name[1]='.')) then
    begin
      DirName := PathName + SearchRec.Name + '\';
      Replace_File(DirName, SL);
    end;
  finally
    Found := FindNext(SearchRec);
  end;
  FindClose(SearchRec);
end;

procedure TForm_Q_20932619.Button1Click(Sender: TObject);
var
  C:             Char;
  I:             Integer;
  PCRootPathName:PChar;
  DriveType:     DWORD;
  S:             string;
  SL:            TStringList;
begin
  ListBox1.Clear;
  Application.ProcessMessages;
  SL := TStringList.Create;
  try
    for I := 0 to CheckListBox1.Items.Count-1 do
      if (CheckListBox1.Checked[I]) then
        SL.Add(CheckListBox1.Items.Strings[I]);
    for C := 'A' to 'Z' do
    begin
      S := C + ':\';
      PCRootPathName := PChar(S);
      DriveType := GetDriveType(PCRootPathName);
      if (DriveType=DRIVE_FIXED) then  // DRIVE_FIXED is HDD
      begin
        ListBox1.Items.Add('Current scanned HDD is ' + S);
        Application.ProcessMessages;
        Replace_File(S, SL);
      end;
    end;
  finally
    SL.Destroy;
    ListBox1.Items.Add('Done.');
  end;
end;

procedure TForm_Q_20932619.CheckBox1Click(Sender: TObject);
var
  I:             Integer;
begin
  for I := 0 to CheckListBox1.Items.Count-1 do
    CheckListBox1.Checked[I] := CheckBox1.Checked;
end;

end.
0
 

Author Comment

by:dict
ID: 10709333
Dear esoftbg,

Thank you very much. Was possible download your file by my email, yes.

Thank you again.

Dict
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 10710440
Dear dict,
it was very pleasant to help you. I am checking my e-mails rarely and there is always more spam than real expected e-mails, but when I saw ´lebronletchev´ as a sender of an e-mail, I understood what you mean by it.
We can accomplish this question if you accept my comment from 03/28/2004 as a solution with grade A (if you think so).
Thank you,

emil
0

Featured Post

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi Dbf export problem to a Visual Foxpro application 6 190
code issue 8 132
tvirtualstringtree freeze when load too manny images 10 63
Firemonkey allowing RTL on android 6 33
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…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

803 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