'VB Script is taking too long to search for a match in the log file
I have a piece of code (running on WINDOWS 10) which searches for a match in the log files and prints the match to an output file on the mentioned path.
The script does its job very well and searches the match correctly.
Only problem I am facing is that the script is taking too long (on average 12 hours) to search for the match in a single file. (a single file is carrying on average 135,800 lines and each line is carrying on average 1500 characters)
The computer specs are: intel i7 10th Gen (6 cores, 12 thread), 16 GB RAM,
How can this script be further optimized to reduce the search time?
'Wscript.Echo ("Script STARTED @" &Now)
'This will get the generic "desktop-path" for all of the users
Set wshShell = CreateObject( "WScript.Shell" )
userName = wshShell.ExpandEnvironmentStrings( "%UserName%" )
DesktopPath = "C:\Users\" & userName & "\Desktop\Logs\"
'ends here
'Defines the pattern
Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Pattern = Inputbox("Enter the pattern to search for","PATTERN","Enter pattern here:")
'ends here
'Defines the general object for all purposes i.e. reading, writing, creating etc
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1
Set LogsFolder = objFSO.GetFolder(Inputbox("Enter the path to the log files","LOG FILES", DesktopPath))
NewNohupPath = Inputbox("Enter the path to save the output file","OUTPUT FILE", DesktopPath)
Set Nohup = objFSO.CreateTextFile(NewNohupPath &"nohup.txt")
Nohup.WriteLine("Default log_path= C:\Users\Ahsan.Taqveem\Desktop")
Nohup.WriteLine("")
Nohup.WriteLine("Script STARTED @" &Now)
Nohup.WriteLine("--")
for each LogFile in LogsFolder.Files
if lcase(objFSO.getExtensionName(LogFile.path))="log" then
Set SelectedLogFile = objFSO.OpenTextFile(LogFile.path, ForReading)
Do While Not SelectedLogFile.AtEndOfStream
CurrentLine = SelectedLogFile.readline
Set colMatches = objRegEx.Execute(CurrentLine)
If colMatches.Count > 0 Then
For Each strMatch in colMatches
Nohup.WriteLine(CurrentLine)
Next
End If
Loop
SelectedLogFile.Close
End if
Next
'Almost done, finishing stage
Nohup.WriteLine("--")
Nohup.WriteLine("Script FINISHED @" &Now)
Nohup.WriteLine("")
Nohup.WriteLine("")
'Close the opened output file
Nohup.Close
'saves the custom date format for renaming the file
CustomeDate = FormatDateTime(Now, vbShortDate) & "_" & right("0" & hour(time),2) & right("0" & minute(time),2) & right("0" & second(time),2)
'its just renaming the file - appending the date at the start of the file name
objFSO.MoveFile NewNohupPath &"nohup.txt", NewNohupPath & CustomeDate &"-nohup.txt"
'End of script
Wscript.Echo("Script FINISHED @" &Now)
Solution 1:[1]
If you are just searching for a specific string, e.g. want to find all lines that contain "ID", using the InStr() function is significantly faster that using RegEx.
To search using InStr(), you need the string you want to search in and the text you want to search for:
InStr(stringToSearchIn, stringToFind).
When the InStr() function finds a match, it will return the position in the string where the match was found (and will return 0 if no match is found). See InStr function for more details on the funciton.
You can use this in an If statement to only write lines that match your search criteria like so:
If InStr(CurrentLine, searchString) >= 1 Then
Nohup.WriteLine(CurrentLine)
End If
Solution 2:[2]
I recommend using the Sift command line tool to do the regex search. On tests with 10MB log files, the search was approximately 34 times faster than the original script. Here's the script modified to use sift:
Set wshShell = CreateObject( "WScript.Shell" )
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForAppending = 8
Const CmdHide = 0
Const CmdShow = 1
Const Wait2Finish = True
userName = wshShell.ExpandEnvironmentStrings( "%UserName%" )
DesktopPath = "C:\Users\" & userName & "\Desktop\Logs\"
Pattern = Inputbox("Enter the search pattern:","PATTERN","Enter pattern here")
If Pattern="" Then WScript.Quit
LogsFolder = Inputbox("Enter the path to the log files","LOG FILES", DesktopPath)
If LogsFolder="" Then WScript.Quit
NewNohupPath = Inputbox("Enter the path to save the output file","OUTPUT FILE", DesktopPath)
If NewNohupPath="" Then WScript.Quit
Set oLogsFolder = objFSO.GetFolder(LogsFolder)
NohupFilePath = NewNohupPath &"nohup.txt"
Set Nohup = objFSO.CreateTextFile(NohupFilePath)
Nohup.WriteLine("Script STARTED @" & Now)
Nohup.WriteLine("--")
Nohup.Close
For Each LogFile In oLogsFolder.Files
If lcase(objFSO.getExtensionName(LogFile.path))="log" Then
wshShell.Run "cmd.exe /c sift.exe """ & Pattern & """ """ & LogFile.path & """>>""" & NohupFilePath & """",CmdShow,Wait2Finish
End If
Next
Set Nohup = objFSO.OpenTextFile(NohupFilePath,ForAppending)
Nohup.WriteLine("--")
Nohup.WriteLine("Script FINISHED @" & Now)
Nohup.WriteLine("")
Nohup.WriteLine("")
Nohup.Close
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mr Kaos |
| Solution 2 |
