Search code examples
textvbscriptfso

Replacing text function value input on large txt file not work


The expiration.txt file contains 197.015 lines.

foo1; 2020-03-01 13:33;
foo2; 2020-02-01 08:45;
foo3; 2020-01-01 11:30;
...
...
...

On this large txt file I need replaced the all date value from:

  1. 2020-03-01 13:33 to 2020-03-01
  2. 2020-02-01 08:45 to 2020-02-01
  3. 2020-01-01 11:30 to 2020-01-01
  4. ...
  5. ...
  6. 2018-01-01 12:40 to 2018-01-01 ( this is the last line number 197.015 )

I have tried the code below.

Don't have error but the replace input in txt file not work.

The new expiration.txt file remained unchanged.

How to do resolve this ?

Const ForReading = 1
Const ForWriting = 2
intCount = 0
intIndex = 1
Set oFSO = CreateObject("Scripting.FileSystemObject")
str_input = ""
Set oInFile = oFSO.OpenTextFile("expiration.txt", 1)
str_input = oInFile.ReadAll()
Set oRegEx = CreateObject("VBScript.RegExp")
With oRegEx
    .Multiline = True
    .Global = True
    .Pattern = "(\d+)-(\d+)-(\d+)\s(\d+):(\d+):(\d+);"
End With
Do Until oInFile.AtEndOfStream
str_input = oInFile.ReadLine
If (intCount = 0) Then
   str_input = oRegEx.Replace(str_input, "$1-$2-$3;")
   Set oInFile = oFSO.OpenTextFile("expiration.txt", 2)
   oInFile.Write str_input
   oInFile.Close
End If
intCount = intCount + 1
If (intCount = 200) Then
    intCount = 0
    intIndex = intIndex + 1
    oInFile.Close
End If
Loop
oInFile.Close
set oFSO = nothing
WScript.echo "ok"

Solution

  • Try reading each line from the large input file, process the row, then write it to a new output file one row at a time. If necessary, you can delete the original input file, and rename the new output file at the end of your script (after verification).

    Some issues I see with your current script:

    • It's calling both ReadAll() and ReadLine(), which is unnecessary.
    • It's not calling Close for the original ForReading file handle prior to opening the same file again ForWriting.
    • It only tries to translate the first row of the input file (and every subsequent 200th row), when intCount is 0 (zero).
    • The regular expression is expecting seconds to be listed, but your example YYYY-MM-DD hh:mm; date time data does not contain seconds, so the regular expression doesn't match.

    I'm uncertain what the purpose of the intCount = 200 block was doing, so I have ommitted it from my answer. Regardless, I kept the row counter intCount variable intact, just in case you want to use it later.

    Here's a possible fix...

    Option Explicit
    
    Const ForReading = 1
    
    Dim oRegEx : Set oRegEx = New RegExp
    oRegEx.Multiline = True
    oRegEx.Global = True
    oRegEx.Pattern = "(\d+)-(\d+)-(\d+)\s(\d+):(\d+);"
    
    Dim intCount : intCount = 0
    Dim str_input : str_input = ""
    Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
    Dim oInFile : Set oInFile = oFSO.OpenTextFile("expiration.txt", ForReading)
    Dim oOutFile : Set oOutFile = oFSO.CreateTextFile("expiration~2.txt", True)
    Do Until oInFile.AtEndOfStream
        str_input = oInFile.ReadLine()
    
        If oRegEx.Test(str_input) Then
            oOutFile.WriteLine oRegEx.Replace(str_input, "$1-$2-$3;")
        Else
            oOutFile.WriteLine str_input
        End If
    
        intCount = intCount + 1
    Loop
    
    oOutFile.Close
    oInFile.Close
    
    Set oOutFile = Nothing
    Set oInFile = Nothing
    
    ' If necessary, use oFSO to delete the original expiration.txt file here, and rename expiration~2.txt to expiration.txt
    
    Set oFSO = Nothing
    Set oRegEx = Nothing
    
    WScript.Echo "Ok"
    

    Hope this helps.