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