Tag Archives: Replace

VBScript: Recursively Search and Replace in Windows

Recently I needed a command-line tool to perform recursive search and replacement inside text files located in a directory and its subfolders under Windows platforms. Several Open Source and proprietary tools exist but I ended by writing my own VBScript for simplicity, customization and portability reasons.

Command-line:


{CScript [/nologo]|WScript} /Path/to/SearchReplaceInFiles.vbs {Folder Path} {String} {ReplaceStringWith} {*.Extension}

Where:

Folder Path: Folder and its subfolders to find files
String: The string to be searched
ReplaceStringWith: The replacement string
*.Extension: File(s) extension. It can be *.*, *.txt …

Below a sample command-line:


C:\> CScript /nologo C:\Briolidz\Dev\Tools\SearchReplaceInFiles.vbs C:\Briolidz\Dev "My Word 1" "My Word 2" *.txt

SearchReplaceInFiles.vbs forces to run in CScript to prevent a separate popup for each WScript.Echo line.

SearchReplaceInFiles.vbs source code:

'
' Recursive search and replacement inside text files located in a directory and
' its subfolders under Windows platforms.
'
' {CScript [/nologo]|WScript} /Path/to/SearchReplaceInFiles.vbs {Folder Path} {String} {ReplaceStringWith} {*.Extension}
'

' Force script to run in CScript to avoid WScript.Echo messages pop-up box
ForceCScript()

Dim Args, FolderPath, FindString, ReplaceStringWith, FSO

' Check arguments
Args = WScript.Arguments.Count
If Args <> 4 then
 WScript.Echo
 WScript.Echo "Usage : {CScript [/nologo]|WScript} /Path/to/SearchReplaceInFiles.vbs {Folder Path} {String} {ReplaceStringWith} {*.Extension}"
 WScript.Echo
 WScript.Echo " Folder Path: Folder and its subfolders to find files"
 WScript.Echo " String: The string to be searched"
 WScript.Echo " ReplaceStringWith: The replacement string"
 WScript.Echo " *.Extension: file(s) extension. Can be *.*, *.txt ..."
 WScript.Echo
 WScript.Quit(1)
end If

' Get arguments
FolderPath = WScript.Arguments(0)
FindString = WScript.Arguments(1)
ReplaceStringWith = WScript.Arguments(2)
Extension = WScript.Arguments(3)

' Creating File System Object
Set FSO = CreateObject("Scripting.FileSystemObject")

' Check extension format
If Not Left(Extension, 2) = "*." Then
 WScript.Echo("Invalid extension " & Extension)
 WScript.Quit(1)
End If

' Check destionation folder
If Not FSO.FolderExists(FolderPath) Then
 WScript.Echo("Folder " & FolderPath & " does not exist !")
 WScript.Quit(1)
End If

' Files extension
Extension = LCase(Mid(Extension, 3))

' Call the GetFiles function to get all files
WScript.Echo
WScript.Echo("Searching for *." & Extension & " files in " & FolderPath & " folder ...")
GetFiles FolderPath, Extension
WScript.Echo("Completed")

Set FSO = Nothing

Function ForceCScript()
 Dim StrArg, Str

 If Not LCase(Right(WScript.FullName, 12)) = "\cscript.exe" Then
  For Each StrArg In WScript.Arguments
   If InStr(StrArg, " ") Then StrArg = """" & StrArg & """"
   Str = Str & " " & StrArg
  Next

  StrCmd = "CScript //nologo """ & WScript.ScriptFullName & """" & Str
  Set WshShell = CreateObject("WScript.Shell")

  ' Rerun the script in CScript
  Set ObjExec = WshShell.Exec(StrCmd)

  ' Wait until the script exits
  Do While ObjExec.Status = 0
   WScript.Sleep 100
  Loop

  ' Exit with CScript's return code
  WScript.Quit ObjExec.ExitCode

  Set WshShell = Nothing
  Set ObjExec = Nothing
 End If
End Function

Function GetFiles(FolderPath, Extension)
 On Error Resume Next

 Dim ObjFolder, ObjSubFolders
 Dim ObjFiles, ObjFile

 Set ObjFolder = FSO.GetFolder(FolderPath)
 Set ObjFiles = ObjFolder.Files

 ' Write all files to output files
 For Each ObjFile In ObjFiles
  StrExtension = LCase(FSO.GetExtensionName(ObjFile))

  If Extension = "*" Or StrExtension = Extension Then
   ' Read source text file
   FileContents = GetFile(ObjFile)

   ' Replace all string In the source file
   NewFileContents = Replace(FileContents, FindString, ReplaceStringWith, 1, -1, 1)
   If NewFileContents <> FileContents Then
    ' Write result If different
    WScript.Echo(" Updating File: " & ObjFile.Path)
    WriteFile ObjFile, NewFileContents
   End If
  End If
 Next

 ' Getting all subfolders
 Set ObjSubFolders = ObjFolder.SubFolders

 ' Getting all Files from subfolder
 For Each ObjFolder In ObjSubFolders
  GetFiles ObjFolder.Path, Extension
 Next
End Function

' Read text file
function GetFile(FileName)
 If FileName <> "" Then
  Dim FS, FileStream

  Set FS = CreateObject("Scripting.FileSystemObject")

  on error resume Next
  Set FileStream = FS.OpenTextFile(FileName)
  GetFile = FileStream.ReadAll
 End If
End Function

' Write string As a text file
function WriteFile(FileName, Contents)
 Dim OutStream, FS

 on error resume Next
 Set FS = CreateObject("Scripting.FileSystemObject")
 Set OutStream = FS.OpenTextFile(FileName, 2, True)
 OutStream.Write Contents
End Function