SEARCH AND REPLACE IN FILES VIA AN ASP PAGE

By Peter A. Bromberg, Ph.D.

Peter Bromberg  


I've always been a big proponent of freeware and shareware. But sometimes it's just better to "roll your own" -- recently I needed to replace a string in a whole bunch of web files. So I went on the web and started trying some shareware and freeware "Search and replace" utilities. What I found, much to my dismay, was that almost every one was unable to replace multiple occurrences of the target string in a single file!   When I finally found one that was able to, an annoying NAG SCREEN popped up informing me that this feature was only available to REGISTERED USERS! Well, I had already wasted an hour of my time and I wasn't about to drop $30 bucks for a one-time job.

My Grandmother (who lived to be 100 but knew very little about computer programming) alway said, "The way to understand recursion is to understand recursion." So, I said "OK - I'll just write my own." I did, and here it is - 100% free and uncrippled, along with some nice comments in the code to show how it was done:



<%
option Explicit
Response.Buffer = False REM turn off response buffering so we can see the output as it's created
REM if the form hasn't been posted, write out the form code:
if Request.form("SearchText") = "" Then
With Response
.write "<head></head><BODY ><Basefont face=Tahoma><TITLE>Search and Replace</TITLE><h2><Center>Search and Replace in Files</h2></center><BR><div align=center id=status></div><BR><BR>"

.write "<FORM ACTION=SearchAndReplace.asp METHOD=POST>"
.Write "<TABLE CELLSPACING=2 CELLPADDING=2 BORDER=0 BGCOLOR=#FFCC66 WIDTH=550 ALIGN=CENTER>"
.write "<TR BGCOLOR=#ff66cc style=""font-face=Verdana;font-size=10pt;""><TD COLSPAN=2 ALIGN=justify>Script will begin at the folder where it is HTTP loaded from and recurse ALL subfolders. Script is set up to look in .HTM, .ASP and .JS files. IMPORTANT! Make sure you run attrib -r /s to remove read - only attributes first or Script will ***BOMB**!!!<BR> This script is CASE SENSITIVE for the Replacement Term, but not for the Search Term.</TD></TR>"
.write "<TR><TD><INPUT TYPE=TEXT NAME=SearchText SIZE=60></TD><TD>Search Term</TR>"
.write "<TR><TD><INPUT TYPE=TEXT NAME=ReplaceText SIZE=60></TD><TD>Replacement Term</TR>"
REM.write "<INPUT TYPE=TEXT NAME=SC VALUE=.>SCOPE (. or /)<BR>"
REM disabled above line to keep scope in current folder and subfolders
.write "<TR><TD COLSPAN=2 ALIGN=CENTER><INPUT TYPE=SUBMIT VALUE=""FIND AND REPLACE""></FORM></TD></TR></TABLE></CENTER>"
end with
else
REM make sure the user doesn't set up an infinite loop--
if UCase(Request.form("SearchText"))=UCase(request.Form("ReplaceText")) then
Response.write "<CENTER>Cannot have identical Search and Replace Terms <BR> <A href=searchandreplace.asp>Search Again</a></CENTER>"
Response.end
end if

REM set sufficient script timeout in case there's lots of files
Server.ScriptTimeout = 6000

REM declare our variables and constants
Dim objFolder
Dim strSearchText
DIm strReplaceText
Dim objfso
Dim sc
Dim begpos
Dim endpos
Dim slen
Const ForReading = 1
Const ForWriting = 2
Const TriStateFalse =0
Dim numItems
strSearchText = Request.Form("SearchText")
strReplaceText = Request.Form("ReplaceText")
REM create the FSO and Folder objects
Set objfso = Server.CreateObject("Scripting.FileSystemObject")
sc = Request.form("SC")
REM comment out next line to enable SCOPE (e.g. "."=curdir, "/"=full site , "../"=one directory up, etc.)
REM and Enable form field for same.

sc ="."
Set objFolder = objFSO.GetFolder(Server.MapPath(sc))
Dim sResult
sResult ="<head></head><BODY ><TITLE>Search And Replace</TITLE><h2><Center>Search And Replace in Files</h2></center><BR><div align=center id=status></div><BR><BR>"
Search objFolder
if numItems = "" then numItems = "0"
sResult =sResult & "<BR><script language=Javascript>document.all.status.innerHTML="""&numItems&" Files Fixed. <BR> <A href=searchandreplace.asp>Search Again</a>"";</script></body></html>"
Response.write sResult

REM this is the primary function
Function Search(objFolder)
dim bolFileFound
Dim objSubFolder
Dim sext
Dim sTitle
Dim objFile
Dim objTextStream
Dim strFileContents

sLen = Len(strSearchText)

REM iterate through the files - load each file and look for the search term
For Each objFile in objFolder.Files

REM set up our file extension filter (you could customize this if you wanted)
sext = Ucase(mid(objFile.Name, Len(objFile.Name)-3, 4))
if sext = ".HTM" or sext = ".TXT" or sext = ".ASP" or mid(sext,2,3)=".JS" then

REM Use ReadBytes Method - up to 100 times faster
dim objFS
dim objTS
dim objFilWrite
dim filpath
set objFile = objFSO.GetFile(objFile.Path)
set objTS = objFile.OpenAsTextStream(ForReading, TristateFalse)
strFileContents =objTS.Read(objFile.Size)
objTS.Close
set objTS= Nothing
filpath=objFile.Path
set objFile=Nothing
Dim stemp
dim Mytemp
dim iters
dim outText

REM we set stemp equal to the first occurence of the search string. We'll use this for our
REM replacing as this will avoid case problems.
stemp =InStr(1, strFileContents, strSearchText, 1)
iters=0
While sTemp >0
If sTemp >0 then
iters=iters+1
Mytemp=mid(strFileContents,stemp,sLen)
strFileContents= Replace (strFileContents, Mytemp, strReplaceText)
REM now rewrite the file
REM on error resume next
Set objFSO= Nothing
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
set objFilWrite = objFSO.OpenTextFile(filpath, ForWriting, True)
objFilWrite.Write strFileContents
objFilWrite.Close
Set objFilWrite=Nothing

REM increment the number of files we've fixed
numItems = numItems +1
if iters > 0 then outText = numItems & ".)&nbsp;FIXED: " & filpath & "&nbsp; Passes: " & iters & "<BR>"
End If
sTemp =InStr(1, strFileContents, strSearchText, 1)
Wend

if outText <> "" then Response.write outText
outText = "" : iters=0

REM cleanup
set objFile=Nothing
Set objTS= Nothing
end if REM end file contents test
if err.number <> 0 then
response.write err.description & "<BR>"
err.clear
end if
Next
REM For each subfolder in this directory, recursively run the Search function again
For Each objSubFolder in objFolder.SubFolders
Search objSubFolder
Next
End Function
end if
%>

This page will interate through all files and subfolders/ files, starting at the folder from which it was HTTP loaded, and perforrm a replacement of all occurences of your chosen search string with the entered replacement string. Have fun, and practice "safe computer". Please be advised that since this script has the potential to be misused, Eggheadcafe.com and the author can not be held responsible for the results of its use. At a minimum, I would recommend you make a BACKUP of the folders containing the files you want to search and replace prior to using the script!!!

 

Peter Bromberg is an independent consultant specializing in distributed .NET solutionsa Senior Programmer /Analyst at in Orlando and a co-developer of the EggheadCafe.com developer website. He can be reached at pbromberg@yahoo.com

Do you have a question or comment about this article? Have a programming problem you need to solve? Post it at eggheadcafe.com forums and receive immediate email notification of responses.


Search

search