How Can I Add a Word to a Text File if That Word Isn’t Already in the File?

How Can I Add a Word to a Text File if That Word Isn’t Already in the File?

  • Comments 1
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I check a text file to see if a word appears in that file and, if it doesn’t, add the word to the file?

-- JO

SpacerHey, Scripting Guy! AnswerScript Center

Hey, JO. We seem to have gotten quite a few questions on this topic lately. You mentioned adding words to a custom dictionary for Microsoft Word; other people mentioned adding an entry to an LMHosts file or something similar. What we’ll do today is provide a generic solution - adding a computer to a list of computer names stored in a text file - but you shouldn’t have any problem adapting our generic example to your specific needs.

To begin with, let’s assume we have a very simple text file (C:\Scripts\Computers.txt) that features the names of all our computers, one computer per line:

atl-dc-01
atl-dc-02
atl-dc-03

We just got a new computer - atl-dc-99 - and we want to add that to the list, provided, of course, that atl-dc-99 isn’t already on the list. To do that we need to read through Computers.txt and see if atl-dc-99 is already in there. If it is, we’re done; if it isn’t, we need to programmatically add the computer to the list. This is going to require three steps: read the file; check to see if the computer is already in there; and, if necessary, add the computer to the file.

Let’s start with reading the file. Here’s some code that will open the file C:\Scripts\Computers.txt, read the entire contents into a variable named strWordList, and then close the file:

Const ForReading = 1
Const ForAppending = 8

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile _
    ("C:\Scripts\Computers.txt", ForReading)
strWordList = objFile.ReadAll
objFile.Close

We begin by defining two constants - ForReading and ForAppending - that we’ll use when working with the text file. For now the only constant we need is ForReading, which tells the FileSystemObject that we want to open a file and read the contents. (You can open a file for reading, for writing, or for appending, but you can’t perform more than a single operation at any one time.)

Next we create an instance of the FileSystemObject and use the OpenTextFile method to open the file for reading. We then use the ReadAll method to read the entire file and store the contents in the variable strWordList. With that done, we call the Close method to close the file.

Note. Why close the file so soon after opening it? Well, if atl-dc-99 is already in the file, then we’re basically done; we won’t need to do anything more with Computers.txt. But what if atl-dc-99 isn’t in the file? In that case, we need to append the new computer to the file; however, as we mentioned, we can’t simultaneously read from and append to a file. Consequently, we need to close the file (which was initially opened for reading) and then reopen it, this time for appending.

So much for step 1. In step 2, we need to determine whether atl-dc-99 is already included in our text file. To do that, we start by defining the string we’re searching for, something we do here:

strSearchWord = "atl-dc-99" & vbCrLf

Notice that we’re constructing a string that consists of the search word (atl-dc-99) plus another carriage return-linefeed. Why go to all that trouble? Well, we want to make sure that any instance of atl-dc-99 we find is a complete computer name and not part of a computer name. Suppose we didn’t specify that a carriage return-linefeed comes before and after our search word, suppose we just said, “Find all instances of atl-dc-99.” In that case, all of these computer names would be scored as “hits:”

atl-dc-999
atl-dc-9999
atl-dc-99-mail-server

You get the idea. We want to ensure that any instance of atl-dc-99 is on a line all by itself, like this:

atl-dc-99

In other words, did the person who created the list type the name atl-dc-99 and then press ENTER? That’s why we look for a carriage return-linefeed immediately following atl-dc-99.

Note that even this approach isn’t foolproof; for example, the script will be “fooled” by a name like this:

seast-atl-dc-99

There are ways to work around problems like this, but they get a little more complicated. If you’re interested, you might take a look at the Scripting Guys webcast on using regular expressions.

So how can we tell if our search term appears in the text file? Well, remember, we have the contents of the file stored in the variable strWordList. Because of that we can use the VBScript InStr method to determine whether or not our search term appears anywhere in the file:

If InStr(strWordList, strSearchWord) = 0 Then

If found, InStr will return the character position in the variable where the search term begins; if the search term can’t be found, then InStr returns a 0. To determine whether or not atl-dc-99 is already in the text file, we just check the return value for InStr. If this value is anything other than 0, that means the search term was found and we’re done. If the return value is 0, then we need to add atl-dc-99 to the text file. We do that with these lines of code:

Set objFile = objFSO.OpenTextFile _
    ("C:\Scripts\Computers.txt ", ForAppending)
objFile.WriteLine "atl-dc-99"
objFile.Close

All we do here is reopen the file - this time for appending - and then use the WriteLine method to write atl-dc-99 at the bottom of the file. (By definition, “appending” to a file adds the information to the end of the file.) We then close the file, and move on to bigger and better things.

Here’s what the completed script looks like:

Const ForReading = 1
Const ForAppending = 8

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile _
    ("C:\Scripts\Computers.txt", ForReading)
strWordList = objFile.ReadAll
objFile.Close

strSearchWord = "atl-dc-99" & vbCrLf

If InStr(strWordList, strSearchWord) = 0 Then
    Set objFile = objFSO.OpenTextFile _
        ("C:\Scripts\Computers.txt ", ForAppending)
    objFile.WriteLine "atl-dc-99"
    objFile.Close
End If
Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi,

    Where i am facing a issue like you mention above "Note that even this approach isn’t foolproof; for example, the script will be “fooled” by a name like this: seast-atl-dc-99"

    Now i am facing this issue. can you please guide me how to solve this ?

    Sheeraz