| Home | “‘_PERL_SandR.bat’ saves a lot of time and trouble if you want to perform the same ‘search and replace’ operation on more than one file.” | Intermediate version | Advanced version |

Free Download: Program for Performing a Multiple File Global Search and Replace (Basic)

By Howard Best, February 11, 2008

(LLBest.com)


“_PERL_SandR.bat” (contained in “_REPLACE.ZIP” - Download now) works with all versions of Windows.

NOTE: “_REPLACE.EXE” is no longer being made available. The reason for this is that, under certain rare circumstances, one or more of the text files being edited would be truncated with no notice given, so if you still have this program, use it at your own risk!

NOTE: This web page assumes that you have downloaded and installed Perl in a folder named “C:\Perl”. Go to Program in Perl on Your Windows Computer” for instructions on how to do this. (Use the ALTERNATE METHOD.)

NOTE: Before performing a multiple file global search and replace using the following method, make sure that you have backup copies of all of the files that you are editing!

“_PERL_SandR.bat” saves a lot of time and trouble if you want to perform the same “search and replace” operation on more than one file. In order to perform one or more search and replace operations on multiple files, you simply change a couple of lines in “_PERL_SandR.bat,” and then double click on it’s icon.

One thing that I really like about this method is that, unlike other methods, it does not change the time/date stamp of files which it doesn’t change. This makes it very easy to separate the modified files by sorting by “Date Modified.”


Note: If any of the following lines are cut off on the right, try using IE’s “View/Text Size” to make the text smaller.

@echo off
if "%OS%" == "Windows_NT" goto WinNT
C:\Perl\bin\perl -x -S "%0"
goto endofperl
:WinNT
C:\Perl\bin\perl -x -S %0
if NOT "%COMSpEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl
if %errorlevel% == 9009 echo You do not have perl in your PATH.
if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
goto endofperl
#!perl -w
#line 12

use File::Copy;

sub printIt
 {
 $s=shift;
 print $s;
 print LOG $s;
 }

sub SandR
 {
 $search=shift;
 $replace=shift;
 &printIt("~s`$search`$replace`\n");
 $changes+=($buffer=~s`$search`$replace`);
 }

sub SandRg
 {
 $search=shift;
 $replace=shift;
 &printIt("~s`$search`$replace`g\n");
 $changes+=($buffer=~s`$search`$replace`g);
 }

$0=~/.*\\(.*)/;
$thisFileName=Win32::GetLongPathName($1);
$logFileName=$thisFileName;
$logFileName=~s/\.\w+?$/.log/;
open(LOG,">$logFileName") or die "Can't open \"$logFileName\": $!.\n";
$dirname=".";
$fcount=0;
$totalChanges=0;

##### Change the following to the file name extension(s) of the files you wish to edit:
$filenamemask='\.(htm|html)$';

opendir(DIR, $dirname) or die "Can't opendir \"$dirname\": $!.\n";
print"\n";
while(defined($fname=readdir(DIR)))
 {
 if(($fname=~m/$filenamemask/i)&&($fname ne $thisFileName))     # Test for desired file name.
  {
  $fcount++;
  $changes=0;
  open(IN,$fname) or die "Can't open \"$fname\": $!.\n";
  $tempfile='C:\\temp.tmp';
  open(OUT,">$tempfile") or die "Can't open \"$tempfile\": $!.\n";
  @buffer=<IN>;
  close(IN);
  $"="";
  $buffer="@buffer";

  ##### The format for the following is 'search string','replacement string':
  SandRg('</html>?','</html>');

  print OUT $buffer;
  close(OUT);
  if($changes)
   {
   copy($tempfile,$fname) or die "Copy to \"$fname\" failed: $!";
   $totalChanges+=$changes;
   &printIt("$changes changes made to file \"$fname\".\n\n");
   }
  else
   {
   &printIt("No changes made to file \"$fname\".\n\n");
   }
  }
 }
closedir(DIR);
&printIt($fcount?"$totalChanges total changes made to $fcount \"$filenamemask\" file(s).\n":"No \"$filenamemask\" files found.\n");
close(LOG);
print"File \"$logFileName\" created.\n\n";

__END__
:endofperl
if exist C:\temp.tmp del C:\temp.tmp
pause

Listing of “_PERL_SandR.bat”

EXAMPLE #1: Suppose that you want to update a folder full of a mixture of “.htm” and “.html” files, some of which may be missing the > character on the end of the </html>. You also want to check to make sure that each .htm file has one and only one </html>. The following are lines 49 and 68 from the above .bat file, which are designed to do the job:

$filenamemask='\.(htm|html)$';
  SandRg('</html>?','</html>');
You simply put “_PERL_SandR.bat” into the same folder as the .htm / .html files and double click on it’s icon. Each .htm / .html file should result in one and only one change. Other than exactly one change per file means that </html> occurs more than once or not at all.

Line 49 could be shortened as follows:

$filenamemask='\.html?$';


EXAMPLE #2: Suppose that you have a folder containing more than 100 .htm files, each one containing the string: http://yourwebsite.com/..., and you want to change each of the ... strings to the file name of that particular .htm file. Using this web page as an example, http://LLBest.com/... should be changed to http://LLBest.com/_REPLACE.htm. The following shows how lines 49 and 68 should be changed in order to get the job done in fine style:

$filenamemask='\.htm$';
  SandR('http://LLBest.com/\.\.\.',"http://LLBest.com/$fname");
Please note that the replacement string is enclosed in double quotes instead of single quotes. The reason for this is that double quotes will cause the variable, “$fname,” to be replaced by the actual file name, in this case: “_REPLACE.htm”.


EXAMPLE #3: Suppose that you want to change two lines of the internal style sheets of a large number of “.htm” and “.html” files. The following is a possible example of how lines 49 and 68 might be changed in order to accomplish such a task:

$filenamemask='\.html?$';
  SandR('
h1{text-align:center;font:normal 150% Verdana;margin:0;margin-top:0.1em;}
h3{text-align:center;font:normal 110% Arial;margin:0;margin-top:0.1em;}','
h1{text-align:center;font-weight:normal;font-size:150%;margin:0;margin-top:0.1em;}
h3{text-align:center;font-weight:normal;font-size:110%;margin:0;margin-top:0.1em;}');
Please note that even though line 68 was replaced with 5 lines, these 5 lines cause only one call to the function, “SandR(…).”


Note: Both lines 49 and 68 use what are called Regular Expressions.

For more examples of search / replacement string syntax using Regular Expressions, see http://LLBest.com/RegularExpressions.htm.

For complete documentation on Regular Expressions, see http://ashutoshsaxena.tripod.com/jstut/quickstart/ch080.html.

Questions, comments and suggestions are welcome.
Howard Best ()


| Home | THIS WEB PAGE URL: http://LLBest.com/_REPLACE.htm | Intermediate version | Advanced version |