Wednesday, May 26, 2010

How to Alter Text Based Files en Mass

So I've spent the better part of a week trying to figure out how best to synchronize a production IT application with its Disaster Recovery counter part while editing the necessary configuration files in an automated fashion. The result is a pretty, dare I say it? BITCHIN set of scripts that will ease my administrative headaches by ten fold.

There are two methods that I am using. I call both methods from a batch script, but you could execute them straight from command line. I have used this to alter the following file types: .bat, .properties, and .xml. Essentially if it is a text based file that can be read with a text editor, this process can do the job.

Method 1: This method specifies the text file to be edited, while looping through it and replacing a specific text string with an alternate text string (which are both input as a variable).

Method 2: This method dumps a list of text based files into a text file, then reads that text file while combining the input from the text file with a file path location where a large number of text files reside. This then loops through the resultant text files and replacing a specific text string with an alternate text string (which are both input as a variable).

So here it is...
Method 1:
The command would be:
wscript.exe C:\replacespecific.vbs "pathoffiletoedit" "texttobereplaced" "newtextstring"

Simply paste the below content to the .vbs filename and location of your choice.
Const ForReading = 1
Const ForWriting = 2

strFilePath = Wscript.Arguments(0)
strSearchText = Wscript.Arguments(1)
strReplaceText = Wscript.Arguments(2)

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objSearchFile = objFSO.GetFile(strFilePath)
If objSearchFile.Size > 0 Then
Set objFile = objFSO.OpenTextFile(strFilePath, ForReading)
strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText, strSearchText, strReplaceText)

Set objFile = objFSO.OpenTextFile(strFilePath, ForWriting)
objFile.Write strNewText
objFile.Close
End If

Method 2:
The command sequence would be:

dir /B C:\Test\DirContent > C:\Test\list.txt

wscript.exe C:\replace.vbs C:\Test\list.txt "C:\Test\DirContent\" "texttobereplaced" "newtextstring"

or

dir /B "directorywheretextfileslive" > "pathtolistoftextfiles.txt"

wscript.exe C:\replace.vbs "pathtolistoftextfiles.txt" "directorywheretextfileslive/" "texttobereplaced" "newtextstring"

*Note: the "directorywheretextfileslive" entry must have a trailing backslash or the process will fail.

Simply paste the below content to the .vbs filename and location of your choice.
Const ForReading = 1
Const ForWriting = 2
strFileListFileName = Wscript.Arguments(0)
strFilePath = Wscript.Arguments(1)
strSearchText = Wscript.Arguments(2)
strReplaceText = Wscript.Arguments(3)

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(strFileListFileName, ForReading)

Do Until objTextFile.AtEndOfStream
fileToUpdate = objTextFile.Readline
Set objFSO2 = CreateObject("Scripting.FileSystemObject")
Set objSearchFile = objFSO.GetFile((strFilePath + fileToUpdate))
If objSearchFile.Size > 0 Then
Set objFile = objFSO2.OpenTextFile((strFilePath + fileToUpdate), ForReading)
strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText, strSearchText, strReplaceText)

Set objFile = objFSO2.OpenTextFile((strFilePath + fileToUpdate), ForWriting)
objFile.Write strNewText
objFile.Close
End If
Loop

Conclusion:
I have both tasks executing nightly where robocopy.exe pulls the files from production servers, edits the files based on the required parameters that I need and then saves them in the appropriate place. The batch script that I call these from actually cycles through the files several times each time replacing a different string of text...and it works BEAUTIFULLY.

So as I've had great success with this, I hope that you will likewise have great success with it for whatever your purpose may be.