You can use methods of the FileSystemObject object to read from and write to text files.
You use the FileSystemObject object's OpenTextFile method to access a text file. Let's look at a simple script that accesses text files. If the script is called without a parameter, it tries to read the file C:\Autoexec.bat. A dialog box allows the user to specify whether the file's content should be shown in a dialog box or in a browser window (Figure 12-12).
Figure 12-12 Content of a text file shown in a browser window and in a dialog box
To read from a text file, you must first create the FileSystemObject object:
Set fso = CreateObject("Scripting.FileSystemObject") |
You should also check whether the file exists because the script causes a run-time error if a file is missing:
If fso.FileExists(file) Then |
If the file exists, you can try to open the file by using the OpenTextFile method of the FileSystemObject object:
Set txtStream = fso.OpenTextFile(file) |
The parameter file, which contains the path (including the name of the text file), must be passed to the method. If the file doesn't exist, a run-time error occurs. The statement above uses only one parameter, which contains the filename. The method supports some optional parameters to control how text files are opened, as shown here:
Object_name.OpenTextFile(filename[, iomode[, create[, format]]]) |
This statement has the following parameters:
NOTE
You must declare the OpenTextFile constants explicitly in your script because WSH doesn't use predefined names for them. In WSH 2, you can use a .wsf file with a <reference> element that defines a reference to the type library to obtain these constants. (This technique is demonstrated several times in this chapter.)
To read the lines in a text file, you must apply the ReadLine method to the file object. During reading, you must use the atEndOfStream method to check whether the file's end has been reached. The following loop reads a file line by line into a string:
Do While Not (txtStream.atEndOfStream) Text = Text & txtStream.ReadLine & vbCrLf Loop |
After you read the file's content, you can use the variable Text for further processing.
The sample script sets C:\Autoexec.bat as the default file. If no other filename is specified, this file is read and its content is shown. It can be helpful, however, if the user can drag another file to the script file's icon so that the script shows the content of the dragged file. You can do this in VBScript by using the following statements:
file = "C:\Autoexec.bat" ' Default test file ' Try to get a filename from the Arguments collection. Set objArgs = WScript.Arguments ' Create object. If objArgs.Count > 0 Then ' Argument found. file = objArgs(0) ' Set filename to first argument. End If |
After these statements are processed, the variable file contains either the name C:\Autoexec.bat or the path and name of the file dragged to the script's icon. Before you can access the file, you must check whether the file exists:
Set fso = CreateObject("Scripting.FileSystemObject") If fso.FileExists(file) Then ' Check whether file exists. |
The first line creates a reference to the FileSystemObject object. Then you apply the FileExists method to this object to check whether the file exists. If the file doesn't exist, the script can terminate by using the Quit method. If the script exists, you can read the file's content:
Set txtStream = fso.OpenTextFile(file) ' Open text file. Do While Not (txtStream.atEndOfStream) Text = Text & txtStream.ReadLine & vbCrLf Loop |
The OpenTextFile method opens the file. The sample omits optional parameters because you need only read access. Then it uses a loop to read the file by using the ReadLine method. To test whether the end of the file has been reached, the atEndOfStream method is used. This method returns False if the file's end hasn't been reached. After exiting the loop, the string variable Text contains the entire file. The script then shows the file's content in a simple dialog box or a browser window.
To show a simple dialog box in VBScript, you can use this statement:
WScript.Echo Text |
Or you can use a command such as this:
MsgBox Text, vbOKOnly + vbInformation, Title |
If the content of the variable Text contains only a few characters, no problems occur. But if you show the content of a lengthy text file by using the Echo method, the window will be larger than the Desktop. The lower part of the dialog box, which contains the text's trail and the OK button, will be hidden under the taskbar.
Using the VBScript MsgBox call causes a different problem: the text isn't shown in its entirety. The VBScript help says that MsgBox can display a parameter prompt with a maximum length of 1024 characters. If you attempt to show a lengthy text file, however, you see a dialog box that displays only the first part of the file.
The following sample solves this problem by showing a simple dialog box that allows the user to specify a browser window or a dialog box for viewing the file's content (Figure 12-13).
Figure 12-13 Dialog box for selecting the file viewer (browser window or dialog box)
To use Microsoft Internet Explorer to display the content, you can use the following procedure:
ShowWindow Text, Title |
In the samples that follow, the ShowWindow procedure contains the following statements:
Sub ShowWindow(txt, title) Dim oIE, doc1 ' Create Internet Explorer Application object. Set oIE = WScript.CreateObject("InternetExplorer.Application") oIE.Navigate "about:blank" ' Empty HTML document oIE.Visible = 1 ' Internet Explorer is visible. oIE.ToolBar = 0 oIE.StatusBar = 0 ' oIE.Width=600 oIE.Height = 500 Do While (oIE.Busy): Loop ' Important: Wait until Internet ' Explorer is ready. Set doc1 = oIE.Document ' Get Document object. doc1.open ' Open document. ' Write script into the Document object. doc1.writeln "<html><head><title>" & Title & "</title></head>" doc1.writeln "<body bgcolor='#FAF0F0'><pre>" doc1.writeln txt ' Text output doc1.writeln "</pre></body></html>" doc1.close ' Close document for write access. End Sub |
The procedure invokes an Internet Explorer window, writes a valid HTML header, and inserts the content of the submitted string in the browser window. The text itself is formatted using the tags <pre>…</pre>. Then the document is completed with a valid HTML file end (the tags </body></html>). The content of the text file is then shown in a browser window.
Did you notice that the Width property of the browser window isn't set in the procedure? Because the statement to set this property begins with a comment character ('), the browser adjusts the window width based on the length of the lines in the text file.
After implementing the procedure in the sample file, I noticed that some files cause "wrong" results in the browser window. As you can see in Figure 12-14, some lines are shown in bold. Other files (such as HTML files containing forms) are shown as a form in the browser window. I analyzed the HTML source code and found the cause: the ShowWindow procedure simply writes the content of the file to the browser's document window. If the variable Text contains HTML commands embedded in the source code, the browser applies these commands. The results are unpredictable.
Figure 12-14 Text shown in bold in the browser window
For example, if you show a script file that contains statements for writing HTML code to the browser window, these statements affect the browser window. Therefore, you need a "filter" that converts the HTML. First, the tag characters < and > must be converted to < and >.
I decided to write my own filter function, MakeHTMLCode, to convert the string to a format that can be displayed as an HTML document. Besides the tag characters < and >, I decided also to filter all carriage return/line feed codes in the string and convert them to <br> tags so that you can display text in the browser window without inserting all of it into <pre>…</pre> tags. Unfortunately, in HTML a space character is treated as a "white space" character, which means that multiple spaces are stripped off the HTML code and the browser displays only a blank. I then tried to convert the blanks in the string to entities, but the result of several entities in an HTML file depends on the browser used. In Internet Explorer 5, multiple blanks are treated as one blank. I then decided to use a second parameter in the filter function MakeHTMLCode, which controls the filter options. A value of 0 forces the filter to convert all < and > characters. A value of 1 processes the string (as the value 0 does) and converts all line breaks to <br> tags. A value of 2 works like a value of 1 but also forces the filter to convert blanks to entities.
At this point, I'd like to make a few remarks about converting patterns in a string. Version 5 of VBScript and JScript support a regular expression object. You can create this object in VBScript as follows:
Set oReg = New RegExp |
You can then set the properties of this object by using methods such as Replace to convert patterns in a string. If all matches in a string are to be processed, you can set the Global property to True:
oReg.Global = True |
The following command specifies that pattern matching not be case sensitive:
oReg.IgnoreCase = True |
To replace all < characters in a string, you can use the following statements:
oReg.Pattern = "<" txt = oReg.Replace(txt, "<") |
The first line sets the pattern, and the second line applies the Replace method to the string txt. The string < is the replacement expression. Here is the entire source code:
Sub MakeHTMLCode(txt, flag) ' Convert text file to HTML structure. ' Flag controls which elements are converted. ' Use the following values: ' 0: Convert all < and > characters to < and >. ' 1: Like flag = 0, but also sets vbCrLf to <br> tag ' (forces line wrap). ' 2: Like flag = 1, but also sets blanks to . ' ### Be careful of the order of pattern replacement. ### Dim oReg Set oReg = New RegExp ' Create regular expression. oReg.Global = True ' All matches oReg.IgnoreCase = True ' Make case insensitive. ' Replace all < with <. oReg.Pattern = "<" ' Set pattern. txt = oReg.Replace(txt, "<") ' Replace all ">" with ">" oReg.Pattern = ">" ' Set pattern. txt = oReg.Replace(txt, ">") If flag > 0 Then ' Replace vbCrLf? ' Now we're ready to replace all vbCrLf with <br>. oReg.Pattern = vbCrLf ' Set pattern. oReg.Global = True ' All matches txt = oReg.Replace(txt, "<br>") End If If flag > 1 Then ' Replace blanks? ' Now we're ready to replace all blanks with . oReg.Pattern = " " ' Set pattern. oReg.Global = True ' All matches txt = oReg.Replace(txt, " ") End If End Sub |
You can use the MakeHTMLCode function to control how the string is filtered. In the sample, the second parameter is set to 0, which forces the filter to simply convert the < and > characters. The carriage return line feed codes remain in the string. Because the text is embedded in <pre>…</pre> tags in the document area, all blanks are unchanged.
The full VBScript implementation is shown in Listing 12-17.
Listing 12-17 ReadTxt.vbs
'************************************************ ' File: ReadTxt.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Reading the content of a text file and ' displaying it in a dialog box. The script ' uses defaults for "iomode." '************************************************ Option Explicit Dim Text, Title Dim fso, objArgs ' Object variables Dim txtStream ' Text stream Dim file ' Filename file = "C:\Autoexec.bat" ' Default test file ' Try to get a filename from the Arguments collection. Set objArgs = WScript.Arguments ' Create object. If objArgs.Count > 0 Then ' Argument found. file = objArgs(0) ' Set filename to first argument. End If Text = "Content of " & file & vbCrLf & vbCrLf Title = "WSH sample - by G. Born" ' Create FileSystemObject object to access the file system. Set fso = CreateObject("Scripting.FileSystemObject") ' Check whether file exists. If fso.FileExists(file) Then Set txtStream = fso.OpenTextFile(file) ' Open text file. Do While Not (txtStream.atEndOfStream) Text = Text & txtStream.ReadLine & vbCrLf Loop Else ' Terminate. MsgBox "File '" & file & "' not found", _ vbOKOnly + vbCritical, Title WScript.Quit 1 ' Terminate with error code. End If If MsgBox("Show results in dialog box?", vbYesNo, Title) _ = vbYes Then ' Show result in message box. MsgBox Text, vbOKOnly + vbInformation, Title Else ' Use browser window for results. MakeHTMLCode Text, 0 ' Convert text to HTML (only < and >). ShowWindow Text, Title ' Show result in HTML window. End If Sub ShowWindow(txt, title) Dim oIE, doc1 ' Create Internet Explorer Application object. Set oIE = WScript.CreateObject("InternetExplorer.Application") oIE.Navigate "about:blank" ' Empty HTML document oIE.Visible = 1 ' Internet Explorer is visible. oIE.ToolBar = 0 oIE.StatusBar = 0 'oIE.Width = 600 oIE.Height = 500 Do While (oIE.Busy): Loop ' Important: Wait until Internet ' Explorer is ready. Set doc1 = oIE.Document ' Get Document object. doc1.open ' Open document. ' Write script to the Document object. doc1.writeln "<html><head><title>" & Title & "</title></head>" doc1.writeln "<body bgcolor='#FAF0F0'><pre>" doc1.writeln txt ' Text output doc1.writeln "</pre></body></html>" doc1.close ' Close document for write access. End Sub Sub MakeHTMLCode(txt, flag) ' Convert text file to HTML structure. ' Flag controls which elements are converted. ' Use the following values: ' 0: Convert all < and > characters to < and >. ' 1: Like flag = 0, but also sets vbCrLf to <br> tag ' (forces line wrap). ' 2: Like flag = 1, but also sets blanks to . ' ### Be careful of the order of pattern replacement. ### Dim oReg Set oReg = New RegExp ' Create regular expression. oReg.Global = True ' All matches oReg.IgnoreCase = True ' Make case insensitive. ' Replace all < with <. oReg.Pattern = "<" ' Set pattern. txt = oReg.Replace(txt, "<") ' Replace all ">" with ">" oReg.Pattern = ">" ' Set pattern. txt = oReg.Replace(txt, ">") If flag > 0 Then ' Replace vbCrLf? ' Now we're ready to replace all vbCrLf with <br>. oReg.Pattern = vbCrLf ' Set pattern. oReg.Global = True ' All matches txt = oReg.Replace(txt, "<br>") End If If flag > 1 Then ' Replace blanks? ' Now we're ready to replace all blanks with . oReg.Pattern = " " ' Set pattern. oReg.Global = True ' All matches txt = oReg.Replace(txt, " ") End If End Sub '*** End |
The following JScript version uses a regular expression object to replace patterns such as < and > with < and >. The JScript exchange method is applied to a text object and requests two parameters. The first parameter must be a regular expression pattern (such as />/ig). The / character encloses the search string; the letter i in ig stands for ignore case, and the g causes a global replace of that pattern in the string object. The second parameter contains the replacement string. The entire JScript version is shown in Listing 12-18.
Listing 12-18 ReadTxt.js
//************************************************ // File: ReadTxt.js (WSH sample in JScript) // Author: (c) G. Born // // Reading the content of a text file and // displaying it in a dialog box //************************************************ var vbYesNo = 4; var vbYes = 6; var vbInformation = 64; var vbQuestion = 32; var vbCancel = 2; var file = "C:\\Autoexec.bat"; var Title = "WSH sample - by G. Born"; // Try to get a filename from the Arguments collection. var objArgs = WScript.Arguments; // Create object. if (objArgs.length > 0) // Argument found. file = objArgs(0); // Set filename to first argument. var Text = "Content of " + file + "\n\n"; // Create FileSystemObject object to access the file system. var fso = WScript.CreateObject("Scripting.FileSystemObject"); // Check whether file exists. if (fso.FileExists(file)) { var txtStream = fso.OpenTextFile(file); // Open text file. while (!txtStream.atEndOfStream) Text = Text + txtStream.ReadLine() + "\n"; } else { WScript.Echo(" File \'" + file + "\' not found"); WScript.Quit(1); } var wsh = WScript.CreateObject("WScript.Shell"); if (wsh.Popup("Show results in dialog box?",0,Title, vbYesNo + vbQuestion) == vbYes) { WScript.Echo(Text); } else { Text = MakeHTMLCode(Text, 0); // Convert text to HTML ShowWindow(Text, Title); // (only < and >) in browser window. } // Helper functions function ShowWindow(txt, title) { // Create Internet Explorer Application object. var oIE = WScript.CreateObject("InternetExplorer.Application"); oIE.navigate("about:blank"); // Empty HTML document oIE.visible = 1; // Internet Explorer is visible. oIE.toolbar = 0; oIE.statusbar = 0; oIE.width=400; oIE.height=500; while (oIE.Busy) {} // Important: Wait until Internet // Explorer is ready. var doc1 = oIE.Document; // Get Document object. doc1.open; // Open document. // Write script to the document object. doc1.writeln("<html><head><title>"); doc1.writeln(Title); doc1.writeln("</title></head>"); doc1.writeln("<body bgcolor=\'#FAF0F0\'><pre>"); doc1.writeln(txt); // Text output doc1.writeln("</pre></body></html>"); doc1.close; // Close document for write access. } function MakeHTMLCode(txt, flag) { // Convert text file to HTML structure. // Flag controls which elements are converted. // Use the following values: // 0: Convert all < and > characters to < and >. // 1: Like flag = 0, but also sets \n to <br> tag // (forces line wrap). // 2: Like flag = 2, but also sets blanks to . // ### Be careful of the order of pattern replacement. ### // Replace all < with <. (Use regular expression.) txt = txt.replace(/</ig, "<"); // Replace all > with >. txt = txt.replace(/>/ig, ">"); if (flag > 0) // Replace \n? txt = txt.replace(/\n/ig, "<br>"); if (flag > 1) // Replace blanks? txt = txt.replace(/ /ig, " "); return txt; } //*** End |
The following short sample opens the Autoexec.bat file, copies the content to a new file, and appends the line Set Born=Hello to the new file. This line causes Windows 95 or Windows 98 to create the environment variable Born at the next system startup.
NOTE
In Windows NT and Windows 2000, you can simply create a test file named C:\Autoexec.bat and add a few text lines to enable the script to run.
To access the text file, you need the FileSystemObject object. The file must be opened using the OpenTextFile method. As mentioned earlier, you can use the parameters passed to the method to control the access mode. The following statement opens the text file for write access. (The named constant ForWriting must be set to 2.)
Set txtStreamOut = fso.OpenTextFile(file2, ForWriting, True) |
If a value of True is passed in the third parameter, the text file is created if it doesn't exist.
NOTE
VBScript doesn't recognize the constant ForWriting, so you must either declare it in the script (if you use .vbs or .js files) or use a .wsf file and define a reference to the type library (as shown in several previous samples).
During the write process (using ForWriting mode), the output file is filled line by line, starting from the beginning of the file. The following sequence copies the content of the text file txtStream to txtStreamOut. Then a new line is appended to the output file.
Do While Not (txtStream.atEndOfStream) ' Copy file content. Text = txtStream.ReadLine ' Read line. txtStreamOut.WriteLine Text ' Write line. Loop ' Append a new line. txtStreamOut.WriteLine "Set Born=Hello" |
The WriteLine method inserts the new line of code automatically during each write access.
The script in Listing 12-19 reads the Autoexec.bat file, creates the output file Autoexec.xx1, copies the content of Autoexec.bat to the output file, and appends the new statement to the output file. After processing, a message box indicates that the file was created (Figure 12-15). If you execute the script several times, the same output file is always created because the write process rewrites the file each time.
Figure 12-15 Dialog box that appears after the Autoexec.bat file is copied
Listing 12-19 WriteTxt.vbs
'************************************************** ' File: WriteTxt.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Copying the content of a text file and appending ' a new line '************************************************** Option Explicit Const file1 = "C:\Autoexec.bat" ' Our test file Const file2 = "C:\Autoexec.xx1" ' The output file ' We must define ForWriting because the ' iomode constants are unknown to VBScript. Const ForWriting = 2 ' iomode: write access Dim Text Dim fso ' Object variable Dim txtStream, txtStreamOut ' TextStream objects ' Create a FileSystemObject object to access the file system. Set fso = CreateObject("Scripting.FileSystemObject") ' Check whether the file exists. If fso.FileExists(file1) Then Set txtStream = fso.OpenTextFile(file1) ' Open input file. Set txtStreamOut = fso.OpenTextFile(file2, _ ForWriting, True) ' Open output file. Do While Not (txtStream.atEndOfStream) ' Copy folder content. Text = txtStream.ReadLine ' Read line. txtStreamOut.WriteLine Text ' Write line. Loop txtStreamOut.WriteLine "Set Born=Hello" ' Append a line. Set txtStream = Nothing ' Release objects. Set txtStreamOut = Nothing WScript.Echo "Text file " & file1 & _ " copied and extended in " & file2 Else WScript.Echo "File " & file & " not found." End If '*** End |
The JScript version (Listing 12-20) has the same structure as the VBScript program. The script creates the output text file Autoexec.xx1 using the Autoexec.bat content and then appends a new line (Figure 12-16).
Figure 12-16 Autoexec.xx1 shown in Notepad
Listing 12-20 WriteTxt.js
//************************************************** // File: WriteTxt.js (WSH sample in JScript) // Author: (c) G. Born // // Copying the content of a text file and appending // a new line //************************************************** var file1 = "C:\\Autoexec.bat"; // Input file var file2 = "C:\\Autoexec.xx1"; // Output file var ForWriting = 2; // iomode: write access var Text; // Create a FileSystemObject object to access the file system. var fso = WScript.CreateObject("Scripting.FileSystemObject"); if (fso.FileExists(file1)) // Check whether the file exists. { var txtStream = fso.OpenTextFile(file1); // Open input file. var txtStreamOut = fso.OpenTextFile(file2, ForWriting, true); // Open output file. while (!txtStream.atEndOfStream) // Copy folder content. { Text = txtStream.ReadLine(); // Read line. txtStreamOut.WriteLine(Text); // Write line. } txtStreamOut.WriteLine("Set Born=Hello"); // Append line. WScript.Echo("Text file " + file1 + " copied and extended in " + file2); } else WScript.Echo("File " + file + " not found."); //*** End |
You might want to append some information to a text file when you process log files and in other situations. You can append new text to an existing text file by using the WriteLine method of the FileSystemObject object. Unlike in the preceding sample, you must set the second parameter to append mode. The following statement causes all data written to the text file to be appended. (The named constant ForAppend must be set to 8 if you use a .vbs or .js file, or else you need to use a .wsf file and define a reference to the type library, as shown in the following sample.)
Set txtStream = fso.OpenTextFile(file2, ForAppend, True) |
The value True in the third parameter forces the method to create a new file if the output text file is missing.
Listing 12-21 opens the C:\Autoexec.xx1 file and appends the text line Set Born=Hello. (The file C:\Autoexec.xx1 is created by the script called WriteTxt.vbs, shown in Listing 12-19.) If you execute the sample several times, the new line is appended each time to the existing file.
Listing 12-21 WriteTxt1.wsf
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- File: WriteTxt1.wsf (WSH 2) Author: (c) G. Born Appending a line to a text file by using a reference to the FileSystemObject type library --> <job id="WriteTxt1"> <reference guid='{420B2830-E718-11CF-893D-00A0C9054228}'/> <script language="VBScript"> <![CDATA[ Option Explicit Const file1 = "C:\Autoexec.xx1" '*** Const ForAppending = 8 ' Obtained from type library Dim Text Dim fso ' Object variable Dim txtStream ' Text stream ' Create a FileSystemObject object to access the file system. Set fso = CreateObject("Scripting.FileSystemObject") If fso.FileExists(file1) Then ' Check whether the file exists. Set txtStream = _ fso.OpenTextFile(file1, ForAppending) ' Output file txtStream.WriteLine "Set Born=Hello" ' Append line. Set txtStream = Nothing ' Release object. WScript.Echo "Text file " & file1 & " extended." Else WScript.Echo "File " & file1 & " not found." End If '*** End ]]> </script> </job> |
The JScript version is shown in Listing 12-22. This solution uses a simple .js file, so the constant ForAppending must be set to 8 within the script. However, you can easily use the code from Listing 12-21 and exchange the VBScript part with the code in this JScript listing and import the named constant ForAppending from the FileSystemObject type library.
Listing 12-22 WriteTxt1.js
//************************************************ // File: WriteTxt1.js (WSH sample in JScript) // Author: (c) G. Born // // Appending a line to a text file //************************************************ var file1 = "C:\\Autoexec.xx1"; var ForAppending = 8; // Writing var Text = "Set Born=Hello"; // Create a FileSystemObject object to access the file system. var fso = WScript.CreateObject("Scripting.FileSystemObject"); if (fso.FileExists(file1)) // Check whether the file exists. { var txtStream = fso.OpenTextFile(file1, ForAppending, true); // Output file txtStream.WriteLine(Text); // Append line. WScript.Echo("Text file " + file1 + " extended."); } else WScript.Echo("File " + file + " not found."); //*** End |
The next sample combines some of the knowledge you gained in the previous sections to read data from an input file, search for patterns, replace all matches with a string, and write the result to another file. The sample reads the TestFile.txt file (which must be in the same folder as the script file) and then changes all occurrences of the ' character to //#. The result is written to a second file, TestFile1.txt.
All you need to do is combine code snippets from previous examples. To get the path to the script file, you can use the following line:
path = GetPath |
The GetPath function contains the following statements:
Function GetPath ' Retrieve the script path. Dim path path = WScript.ScriptFullName ' Script name GetPath = Left(path, InStrRev(path, "\")) End Function |
After retrieving the path, you can open the input file and create the output file by using the following sequence:
Set fso = CreateObject("Scripting.FileSystemObject") If Not fso.FileExists(fileIn) Then WScript.Quit 1 Set oFileIn = fso.OpenTextFile(path & "TestFile.txt") Set oFileOut = fso.OpenTextFile(path & "TestFile1.txt", _ ForWriting, True) |
The first line creates an instance of the FileSystemObject object. The second line checks whether the input file exists. If it does, it's opened using the OpenTextFile method in the third line. Because you need only read access to the file, just the filename is passed as a parameter. The last statement opens the output file. The second parameter submitted to the OpenTextFile method is set to ForWriting so that you can write to the file.
You process the input file and replace all matches with the replacement text by using the following code sequence:
Do While Not (oFileIn.atEndOfStream) Text = oFileIn.ReadLine ' Read a line. Text = Filter(Text, pattern, replacement) oFileOut.WriteLine Text ' Write text. Loop |
The Do While loop terminates if the atEndOfStream method of the input file returns the value True. If the file is empty, atEndOfStream returns True immediately and the loop is skipped; otherwise, atEndOfStream returns True only after ReadLine reads the last line in the file. The second statement within the loop calls the user-defined function Filter, which has three parameters: the first parameter contains the string to be processed, the second parameter specifies the search pattern, and the third parameter specifies the replacement string. The sample specifies the parameters pattern and replacement as constants. The last line within the loop simply writes the text returned from the Filter function to the output file.
The Filter function contains the code that does the replacement. We used a similar approach earlier in the chapter in the ReadTxt.vbs sample, so I reused most of the code for this sample.
Function Filter(txt, expr1, expr2) ' Replaces expr1 with expr2 in text. Dim oReg Set oReg = New RegExp ' Create regular expression. oReg.Global = True ' All matches oReg.IgnoreCase = True ' Make case insensitive. ' Replace all expr1 with expr2 oReg.Pattern = expr1 ' Set pattern. Filter = oReg.Replace(txt, expr2) End Function |
The function creates a regular expression object oReg. Then the properties of this object are set to force a global operation. The Replace method ensures that all occurrences of the parameter expr1 are replaced by the string contained in expr2.
Listing 12-23 shows the full VBScript program.
Listing 12-23 ReplaceTxt.vbs
'************************************************** ' File: ReplaceTxt.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Reading a file, replacing a given pattern in the ' file, and writing the result to another file '************************************************** Option Explicit ' We must define ForWriting because the ' iomode constants are unknown to VBScript. Const ForWriting = 2 ' iomode: write access Const inF = "TestFile.txt" Const outF = "TestFile1.txt" ' Here are the strings for replacement. Const pattern = "'" Const replacement = "//#" Dim Text Dim fso ' Object variable Dim oFileIn, oFileOut ' Text stream Dim path, fileIn, fileOut path = GetPath() ' Retrieve current path to script. fileIn = path & inF ' Create filenames. fileOut = path & outF ' Create a FileSystemObject object to access the file system. Set fso = CreateObject("Scripting.FileSystemObject") If Not fso.FileExists(fileIn) Then ' Input file exists? WScript.Echo "File '" & fileIn & "' not found" WScript.Quit 1 End If ' Input file present; open file and create output file. Set oFileIn = fso.OpenTextFile(fileIn) ' Open input file. Set oFileOut = fso.OpenTextFile(fileOut, _ ForWriting, True) ' Open output file. Do While Not (oFileIn.atEndOfStream) Text = oFileIn.ReadLine ' Read a line. Text = Filter(Text, pattern, replacement) oFileOut.WriteLine Text ' Write text. Loop WScript.Echo "Text file: " & fileIn & vbCrLf & _ "Written into: " & fileOut Function GetPath ' Retrieve the script path. Dim path path = WScript.ScriptFullName ' Script name GetPath = Left(path, InStrRev(path, "\")) End Function Function Filter(txt, expr1, expr2) ' Replace expr1 with expr2 in text. Dim oReg Set oReg = New RegExp ' Create regular expression. oReg.Global = True ' All matches oReg.IgnoreCase = True ' Make case-insensitive. ' Replace all expr1 with expr2. oReg.Pattern = expr1 ' Set pattern. Filter = oReg.Replace(txt, expr2) End Function '*** End |
NOTE
You can extend ReplaceTxt.vbs in a number of ways. For example, you can extend it so that it accepts a matching pattern, a replacement pattern, and one or several filenames. Then you can apply the program to a group of files to replace a given string with a second string.