[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 547
  • Last Modified:

VBScript to Find list of files by ext, open the files and edit the txt on a line in the files

I have a VBScript that will open up a file with .ws file extension, look for text that shows a path name, and replace with new text. What I need to do is a search of the entire hard drive for any files with this file extention and make this same change on them all. Can anyone please help?

Thanks
ReplaceTextTest4.vbs
0
jspade_69
Asked:
jspade_69
  • 16
  • 13
  • 2
1 Solution
 
Bill PrewCommented:
Give this a try, it should search all files in all subfolders.
Const ForReading = 1
Const ForWriting = 2

strFolder = "c:\"
strExtension = ".ws"

Set objFSO = CreateObject("Scripting.FileSystemObject")

DoFolder objFSO.GetFolder(strFolder)

Sub DoFolder(objFolder)
   For Each objFile in objFolder.Files
      If LCase(Right(objFile.Name, Len(strExtension))) = strExtension Then
         DoFile objFile
      End If
   Next

   For Each objSubFolder In objFolder.Subfolders
      DoFolder objSubFolder
   Next
End Sub

Sub DoFile(objFile)
   Set objFile = objFSO.OpenTextFile(objFile.Path, ForReading)

   strText = objFile.ReadAll
   objFile.Close

   strNewText = Replace(strText, "Program Files", "Program Files (x86)")

   Set objFile = objFSO.OpenTextFile(objFile.Path & strExtension, ForWriting)
   objFile.WriteLine strNewText
   objFile.Close
End Sub

Open in new window

~bp
0
 
jspade_69Author Commented:
Hey Bill Thanks for the reply....I ran the script and got the following error: Line 31, Char: 4, Error: Object doesn't support this property or method: 'objFile.Path', Code: 800A01B6
0
 
Bill PrewCommented:
Sorry, missed that conflict between objFile and the code you had that I reused in that SUB.  This should take care of that.
Const ForReading = 1
Const ForWriting = 2

strFolder = "c:\"
strExtension = ".ws"

Set objFSO = CreateObject("Scripting.FileSystemObject")

DoFolder objFSO.GetFolder(strFolder)

Sub DoFolder(objFolder)
   For Each objFile in objFolder.Files
      If LCase(Right(objFile.Name, Len(strExtension))) = strExtension Then
         DoFile objFile
      End If
   Next

   For Each objSubFolder In objFolder.Subfolders
      DoFolder objSubFolder
   Next
End Sub

Sub DoFile(objFile)
   Set objRead = objFSO.OpenTextFile(objFile.Path, ForReading)

   strText = objRead.ReadAll
   objRead.Close

   strNewText = Replace(strText, "Program Files", "Program Files (x86)")

   Set objWrite = objFSO.OpenTextFile(objFile.Path & strExtension, ForWriting)
   objWrite.WriteLine strNewText
   objWrite.Close
End Sub

Open in new window

~bp
0
Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

 
jspade_69Author Commented:
Different error now, same line and char, error is file not found
0
 
Bill PrewCommented:
That looks like a bug in your original code, change this line:

   Set objWrite = objFSO.OpenTextFile(objFile.Path & strExtension, ForWriting)

to:

   Set objWrite = objFSO.OpenTextFile(objFile.Path & strExtension, ForWriting, True)

~bp
0
 
Brent ChallisPrincipal: ITCommented:
Here is a PowerShell solution.

The approach is to use the PowerShell cmdlet Get-ChildItem which has an alias of dir using the -recurse switch to indicate a need to trawl through the sub folders and only select *.ws files.  This collection of files is then piped into the cmdlet that I wrote at the beginning of the file that will test to see if the string you want to change is present it will then go through the lines in the file replacing the text and then outputting the new string in to a file of the original name with a .ws on the end.

function Replace-Text([string]$OriginalText,[string]$ReplacementText)
{
    Begin
    {
    }
    Process
    {
       
        if (([string](Get-Content $_.FullName)).IndexOf($OriginalText) -ge 0)
        {
            $content = Get-Content $_.FullName
            foreach ($line in $content)
            {
                $line.Replace($OriginalText,$ReplacementText) | Out-File ($_.FullName + ".ws") -append
            }
        }
    }
    End
    {
    }
}

dir -path C:\data\Development\Powershell\ScriptQuestion\ -include *.ws -recurse |
 Replace-Text "Program Files" "Program Files (x86)"
0
 
jspade_69Author Commented:
Bill error move to line 33 now, Invalid procedure call or argument
0
 
Bill PrewCommented:
Is line 33 still:

objWrite.Close

if so, what else does the error message say exactly.

~bp
0
 
jspade_69Author Commented:
No line 33 is : objWrite.WriteLine strNewText, and the exact error message is Line 33, Char 4 Error: Invalid Procedure call or argument, Code: 800A0005
0
 
Bill PrewCommented:
I don't see a problem with that statement, can you post up the exact script you are running.

~bp
0
 
jspade_69Author Commented:
Here you go
ReplaceTextTest6.vbs
0
 
Bill PrewCommented:
I ran a test here and it worked fine.  You might want to add the following line at the beginning of the DoFile routine to see if any files are processed correctly, and which file it fails on:

Sub DoFile(objFile)
   Wscript.Echo objFile.Path

~bp
0
 
jspade_69Author Commented:
Hey Bill sorry it took me a while to test but I got more information.



I went back to the orginal code that you gave me and I added the Wscript.Echo objFile.Path as you suggested. I have a test.ws file on the root of C and a test2.ws file on the desktop.

1) The script echos the path for the file on the Root of "C" I click ok and then it echos the this path: C:\$Recycle.Bin\s-1-5-21-XXXXXXX\$I17NV4P.ws.ws. I click ok and then get Error message Line 27, Char 4, Error: INput past end of File, Code 800A003E.  I empty out the recycle bin and run again and it still echos the $Recycle.Bin path with the same error.

2) It does change the Text in the File that it sees on the root of "C" but it creates a new file and addes an additional ".ws" at the end (Test.ws.ws) and it never sees the one on the Desktop...I'm assuming that's because it stops after the error for path C:\$Recycle.Bin
ReplaceTextTest6.vbs
0
 
Bill PrewCommented:
Ah, that makes some sense.  Trying to "use" files in the recycle bin could likely cause a number of different errors, as well as writing into that folder.  Would it make sense to add one or more folders like that to be skipped over in the code?

~bp
0
 
jspade_69Author Commented:
Bchallis,

Thanks for the response... I ran the powershell script and it did a couple of things:

1) it duplicated all the files as opposed to editing and saving the same file and added an extra ".ws" at the end changing the file name to "Test.ws.ws" and in one file it changed the Text to " "Program Files (x86) (x86" and another to "Program Files (x86) (x86) (x86)"
0
 
jspade_69Author Commented:
Bill that would make a lot of sense to skip those kinds of folders...I wouldn't need to check any hidden folders.
0
 
Bill PrewCommented:
Okay, give this a try.
Const ForReading = 1
Const ForWriting = 2

strFolder = "c:\"
strExtension = ".ws"
arrOmit = Array("$RECYCLE.BIN","System Volume Information")

Set objFSO = CreateObject("Scripting.FileSystemObject")

DoFolder objFSO.GetFolder(strFolder)

Sub DoFolder(objFolder)
   Wscript.Echo "Processing folder=" & objFolder.Name
   For Each strOmit in arrOmit
      If LCase(strOmit) = objFolder.Name Then 
         Wscript.Echo "Skipping folder=" & objFolder.Name
         Exit Sub
      End If
   Next
   For Each objFile in objFolder.Files
      If LCase(Right(objFile.Name, Len(strExtension))) = strExtension Then
         DoFile objFile
      End If
   Next

   For Each objSubFolder In objFolder.Subfolders
      DoFolder objSubFolder
   Next
End Sub

Sub DoFile(objFile)
   Wscript.Echo "Processing file=" & objFile.Path
   Set objRead = objFSO.OpenTextFile(objFile.Path, ForReading)

   strText = objRead.ReadAll
   objRead.Close

   strNewText = Replace(strText, "Program Files", "Program Files (x86)")

   Set objWrite = objFSO.OpenTextFile(objFile.Path & strExtension, ForWriting, True)

   objWrite.WriteLine strNewText
   objWrite.Close
End Sub

Open in new window

~bp
0
 
Bill PrewCommented:
Okay, this will skip all HIDDEN folders, as well as any in the arrOmit array.
Const ForReading = 1
Const ForWriting = 2

strFolder = "c:\"
strExtension = ".ws"
arrOmit = Array("$RECYCLE.BIN","System Volume Information")

Set objFSO = CreateObject("Scripting.FileSystemObject")

DoFolder objFSO.GetFolder(strFolder)

Sub DoFolder(objFolder)
   Wscript.Echo "Processing folder=" & objFolder.Name
   If objFolder.Attributes AND 2 Then
      Wscript.Echo "Skipping hidden folder=" & objFolder.Name
      Exit Sub
   End If
   For Each strOmit in arrOmit
      If LCase(strOmit) = objFolder.Name Then 
         Wscript.Echo "Skipping omitted folder=" & objFolder.Name
         Exit Sub
      End If
   Next
   For Each objFile in objFolder.Files
      If LCase(Right(objFile.Name, Len(strExtension))) = strExtension Then
         DoFile objFile
      End If
   Next

   For Each objSubFolder In objFolder.Subfolders
      DoFolder objSubFolder
   Next
End Sub

Sub DoFile(objFile)
   Wscript.Echo "Processing file=" & objFile.Path
   Set objRead = objFSO.OpenTextFile(objFile.Path, ForReading)

   strText = objRead.ReadAll
   objRead.Close

   strNewText = Replace(strText, "Program Files", "Program Files (x86)")

   Set objWrite = objFSO.OpenTextFile(objFile.Path & strExtension, ForWriting, True)

   objWrite.WriteLine strNewText
   objWrite.Close
End Sub

Open in new window

~bp
0
 
jspade_69Author Commented:
BP

That new code states:

1. Processing Folder=    click ok
2. Processing File= c:\test.ws    click ok
3. Processing Folder= $recycle.bin
4. Processing folder=s-1-5-21-xxxxxx
5. Processing File= C:\$Recycle.Bin\s-1-5-21-xxxxxxx\SI17NV4P.ws.ws

And then the same Line 35, char 4 Input past end of life error
0
 
Brent ChallisPrincipal: ITCommented:
The reason that I added the extension to the file name was that your sample code had:
     Set objFile = objFSO.OpenTextFile("C:\TestTextFile.ws.ws", ForWriting)
so I emulated that.

On ethe basis that you want to update the existing file, replacing the body of the foreach loop in the Process section with:
{
            $content = Get-Content $_.FullName
            foreach ($line in $content)
            {
                $line.Replace($OriginalText,$ReplacementText) | Out-File ($_.FullName + ".tmp") -append
            }
            Remove-Item $_.FullName
            Rename-Item -path ($_.FullName + ".tmp") -NewName $_.FullName
        }
should work.
0
 
Bill PrewCommented:
Well, I would expect the recycle bin to be hidden, but I see a bug in the omit logic so let's try this:
Const ForReading = 1
Const ForWriting = 2

strFolder = "c:\"
strExtension = ".ws"
arrOmit = Array("$RECYCLE.BIN","System Volume Information")

Set objFSO = CreateObject("Scripting.FileSystemObject")

DoFolder objFSO.GetFolder(strFolder)

Sub DoFolder(objFolder)
   Wscript.Echo "Processing folder=" & objFolder.Name
   If objFolder.Attributes AND 2 Then
      Wscript.Echo "Skipping hidden folder=" & objFolder.Name
      Exit Sub
   End If
   For Each strOmit in arrOmit
      If LCase(strOmit) = LCase(objFolder.Name) Then 
         Wscript.Echo "Skipping omitted folder=" & objFolder.Name
         Exit Sub
      End If
   Next
   For Each objFile in objFolder.Files
      If LCase(Right(objFile.Name, Len(strExtension))) = strExtension Then
         DoFile objFile
      End If
   Next

   For Each objSubFolder In objFolder.Subfolders
      DoFolder objSubFolder
   Next
End Sub

Sub DoFile(objFile)
   Wscript.Echo "Processing file=" & objFile.Path
   Set objRead = objFSO.OpenTextFile(objFile.Path, ForReading)

   strText = objRead.ReadAll
   objRead.Close

   strNewText = Replace(strText, "Program Files", "Program Files (x86)")

   Set objWrite = objFSO.OpenTextFile(objFile.Path & strExtension, ForWriting, True)

   objWrite.WriteLine strNewText
   objWrite.Close
End Sub

Open in new window

~bp
0
 
jspade_69Author Commented:
BP

now I have

1: Processing Folder=     Click ok
2: Skipping hidden folder=  click ok


and nothing else...I don't think it's processing the other folders now

I tried to compare this last code with the previous and I couldn't find the error...LOL I was hope that I could impression by say Ahh I found the issue but sorry I couldn't. LOL

At least it's not processsing the $Recycle.bin now and generating an error.
0
 
Bill PrewCommented:
Okay, I guess C:\ is indeed a hidden folder, so we have to not skip that one, argh.

Also, if you run this from a command line like this you won't have to press enter on every dsplay message:

cscript EE27643183.vbs
Const ForReading = 1
Const ForWriting = 2

strFolder = "c:\"
strExtension = ".ws"
arrOmit = Array("$RECYCLE.BIN","System Volume Information")

Set objFSO = CreateObject("Scripting.FileSystemObject")

DoFolder objFSO.GetFolder(strFolder)

Sub DoFolder(objFolder)
   Wscript.Echo "Processing folder=" & objFolder.Name
   If objFolder.Name <> "" Then 
      If objFolder.Attributes AND 2 Then
         Wscript.Echo "Skipping hidden folder=" & objFolder.Name
         Exit Sub
      End If
   End If
   For Each strOmit in arrOmit
      If LCase(strOmit) = LCase(objFolder.Name) Then 
         Wscript.Echo "Skipping omitted folder=" & objFolder.Name
         Exit Sub
      End If
   Next
   For Each objFile in objFolder.Files
      If LCase(Right(objFile.Name, Len(strExtension))) = strExtension Then
         DoFile objFile
      End If
   Next

   For Each objSubFolder In objFolder.Subfolders
      DoFolder objSubFolder
   Next
End Sub

Sub DoFile(objFile)
   Wscript.Echo "Processing file=" & objFile.Path
   Set objRead = objFSO.OpenTextFile(objFile.Path, ForReading)

   strText = objRead.ReadAll
   objRead.Close

   strNewText = Replace(strText, "Program Files", "Program Files (x86)")

   Set objWrite = objFSO.OpenTextFile(objFile.Path & strExtension, ForWriting, True)

   objWrite.WriteLine strNewText
   objWrite.Close
End Sub

Open in new window

~bp
0
 
jspade_69Author Commented:
BP,

That ran through with no problem and I had files in three different places and it change the text on the 3 files in the 3 different locationa, but one last thing...instead of editing the existing file and saving it, it created a new file in each location  adding an extra .ws at the end...example the test.ws file on the root of C was changed and save as test.ws.ws, and the test2.ws file on the desktop was changed as saved as test2.ws.ws
0
 
Bill PrewCommented:
Yes, that came out of your original code sample I believe.  So you want it to overwrite the existing file?

~bp
0
 
jspade_69Author Commented:
Yes sir
0
 
jspade_69Author Commented:
BP

Line 42 Set objWrite = objFSO.OpenTextFile(objFile.Path & strExtension, ForWriting, True)


I removed the "& strExtension"    and it work!!!! it made the change to the original file and save it.
0
 
jspade_69Author Commented:
BP Thanks for the great help and the great patients.
0
 
jspade_69Author Commented:
BChallis,

I'm going to keep playing with the powershell option as well to see if I can get it wor work.  this is the new file with the new changes you gave me but it barked at me

CategoryInfo          : ParserError: (}:String) [], ParseException
FullyQualifiedErrorId : UnexpectedToken

maybe I didn't added the change properly....less formiliar with powershell.

function Replace-Text([string]$OriginalText,[string]$ReplacementText)
{
    Begin
    {
    }
    Process
    {
            $content = Get-Content $_.FullName
            foreach ($line in $content)
            {
                $line.Replace($OriginalText,$ReplacementText) | Out-File ($_.FullName + ".tmp") -append
            }
            Remove-Item $_.FullName
            Rename-Item -path ($_.FullName + ".tmp") -NewName $_.FullName
        }

        }
    }
    End
    {
    }
}

dir -path C:\ -include *.ws -recurse |
 Replace-Text "Program Files" "Program Files (x86)"
0
 
jspade_69Author Commented:
BP is amazing in how quickly he responded and how accurate his solution was.
0
 
Bill PrewCommented:
Good morning, glad to see you got where you wanted to be and that I was able to help.  Thanks for the feedback.

~bp
0

Featured Post

NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

  • 16
  • 13
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now