Solved

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

Posted on 2012-03-21
31
536 Views
Last Modified: 2012-06-27
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
Comment
Question by:jspade_69
  • 16
  • 13
  • 2
31 Comments
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37750503
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
 

Author Comment

by:jspade_69
ID: 37750579
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
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37750590
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
 

Author Comment

by:jspade_69
ID: 37750626
Different error now, same line and char, error is file not found
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37750635
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
 
LVL 8

Expert Comment

by:bchallis
ID: 37750639
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
 

Author Comment

by:jspade_69
ID: 37750665
Bill error move to line 33 now, Invalid procedure call or argument
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37750718
Is line 33 still:

objWrite.Close

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

~bp
0
 

Author Comment

by:jspade_69
ID: 37750758
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
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37750770
I don't see a problem with that statement, can you post up the exact script you are running.

~bp
0
 

Author Comment

by:jspade_69
ID: 37750800
Here you go
ReplaceTextTest6.vbs
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37752022
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
 

Author Comment

by:jspade_69
ID: 37755389
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
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37755402
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
 

Author Comment

by:jspade_69
ID: 37755436
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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:jspade_69
ID: 37755442
Bill that would make a lot of sense to skip those kinds of folders...I wouldn't need to check any hidden folders.
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37755443
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
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37755462
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
 

Author Comment

by:jspade_69
ID: 37755474
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
 
LVL 8

Expert Comment

by:bchallis
ID: 37755478
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
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37755507
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
 

Author Comment

by:jspade_69
ID: 37755568
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
 
LVL 51

Accepted Solution

by:
Bill Prew earned 500 total points
ID: 37755625
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
 

Author Comment

by:jspade_69
ID: 37755660
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
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37755669
Yes, that came out of your original code sample I believe.  So you want it to overwrite the existing file?

~bp
0
 

Author Comment

by:jspade_69
ID: 37755678
Yes sir
0
 

Author Comment

by:jspade_69
ID: 37755686
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
 

Author Comment

by:jspade_69
ID: 37755697
BP Thanks for the great help and the great patients.
0
 

Author Comment

by:jspade_69
ID: 37755709
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
 

Author Closing Comment

by:jspade_69
ID: 37755713
BP is amazing in how quickly he responded and how accurate his solution was.
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 37756523
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

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

In this previous article (https://oddytee.wordpress.com/2016/05/05/provision-new-office-365-user-and-mailbox-from-exchange-hybrid-via-powershell/), we made basic license assignments to users in O365. When I say basic, the method is the simplest way …
This article explains how to prepare an HTML email signature template file containing dynamic placeholders for users' Azure AD data. Furthermore, it explains how to use this file to remotely set up a department-wide email signature policy in Office …
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now