【问题标题】:Replace a number in CSV file with VBscript without replacing all text用 VBscript 替换 CSV 文件中的数字而不替换所有文本
【发布时间】:2013-05-24 14:34:29
【问题描述】:

我正在处理这段代码

Dim strFirm,soNumber,strValues,arrStr,strCitrix,NewText,text

strFirm = "Gray"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("cloud.csv",1,True)

Do while not objTextFile.AtEndOfStream
    arrStr = Split(objTextFile.ReadLine, ",")
If arrStr(0) = strFirm Then
    soNumber = arrStr(1)
Exit Do
End If
Loop

objTextFile.Close

strCitrix = soNumber + 1

MsgBox "Cloud Client " & strFirm & " is now using " & strCitrix & " Citrix licenses."

NewText = Replace(soNumber, soNumber, strCitrix)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("cloud.csv",2,True)
objTextFile.Writeline NewText
objTextFile.Close

但是,当我运行代码时,替换会清除文件上的所有文本,但我正在编写的数字除外。

我想要它做的是保留所有其他文本,只更改一个指定的变量。

例子

Client1,5
Client2,7
Client3,12
Gray,6
Client4,9
Client5,17
Client6,8

运行脚本后

Client1,5
Client2,7
Client3,12
Gray,7
Client4,9
Client5,17
Client6,8

谁能指出我做错了什么?

提前感谢您的帮助。

【问题讨论】:

    标签: text vbscript replace


    【解决方案1】:

    您的输出文件仅包含您要更改的数字,因为您从文件中读取的文本中仅提取了该数字:

    soNumber = arrStr(1)
    

    加一:

    strCitrix = soNumber + 1
    

    soNumber 中的数字(无论如何只包含数字)替换为递增的数字:

    NewText = Replace(soNumber, soNumber, strCitrix)
    

    然后只将新数字写回文件:

    objTextFile.Writeline NewText
    

    要保留您想要保留的原始内容的那些部分,您还需要将它们写回文件,而不仅仅是修改后的内容。

    如果您逐行读取源文件(在处理大文件时这是一个好主意,因为它可以避免内存耗尽),您应该在执行过程中将输出写入一个临时文件:

    Set inFile  = objFSO.OpenTextFile("cloud.csv")
    Set outFile = objFSO.OpenTextFile("cloud.csv.tmp", 2, True)
    
    Do while not objTextFile.AtEndOfStream
      line = inFile.ReadLine
      arrStr = Split(line, ",")
      If arrStr(0) = strFirm Then
        soNumber = CInt(arrStr(1))
        outFile.WriteLine arrStr(0) & "," & (soNumber + 1)
      Else
        outFile.WriteLine line
      End If
    Loop
    
    inFile.Close
    outFile.Close
    

    然后用修改后的文件替换原来的文件:

    objFSO.DeleteFile "cloud.csv", True
    objFSO.MoveFile "cloud.csv.tmp", "cloud.csv"
    

    但是,如果您的输入文件很小,则只需读取整个文件、处理它并用修改后的内容覆盖文件会更容易:

    text = Split(objFSO.OpenTextFile("cloud.csv").ReadAll, vbNewLine)
    
    For i = 0 To UBound(text)
      If Len(text(i)) > 0 Then
        arrStr = Split(text(i), ",")
        If arrStr(0) = strFirm Then
          soNumber = CInt(arrStr(1))
          text(i) = arrStr(0) & "," & (soNumber + 1)
        End If
      End If
    Next
    
    objFSO.OpenTextFile("cloud.csv", 2, True).Write Join(text, vbNewLine)
    

    Len(text(i)) > 0 检查用于跳过空行(包括文件末尾的尾随换行符),因为空字符串被拆分为空数组,这反过来会使检查 arrStr(0) = strFirm 失败并显示 @ 987654331@错误。

    【讨论】:

    • 感谢您的帮助。
    • @AnsgarWiechers +1 用于诊断和逐行方法; .ReadAll() 上的 Split() 策略可以通过至少提及尾随 EOL/空最后一个数组项的问题来改进。
    【解决方案2】:

    对于短文件,我更喜欢 .ReadAll()/RegExp 策略:

      Dim oFS    : Set oFS   = CreateObject("Scripting.FileSystemObject")
      Dim sFirma : sFirma    = "Gray"
      Dim sFSpec : sFSpec    = "..\data\cloud.csv"
      Dim sAll   : sAll      = oFS.OpenTextFile(sFSpec).ReadAll()
      Dim reCut  : Set reCut = New RegExp
      reCut.Global    = True
      reCut.Multiline = True
      reCut.Pattern   = "^(" & sFirma & ",)(\d+)"
      Dim oMTS   : Set oMTS  = reCut.Execute(sAll)
      If 1 = oMTS.Count Then
         oFS.CreateTextFile(sFSpec).Write reCut.Replace(sAll, "$1" & (CLng(oMTS(0).SubMatches(1)) + 1))
      Else
         ' handle error
      End If
      WScript.Echo oFS.OpenTextFile(sFSpec).ReadAll()
    

    输出:

    Client1,5
    Client2,7
    Client3,12
    Gray,7
    Client4,9
    Client5,17
    Client6,8
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-07
      • 2013-11-28
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多