?
Solved

Search/Replace

Posted on 2004-03-25
10
Medium Priority
?
312 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
[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
  • 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
Industry Leaders: 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!

 
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 400 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

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.

Question has a verified solution.

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

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…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
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.
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 Month11 days, 11 hours left to enroll

752 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