【问题标题】:remove nul characters from text file using vbs使用 vbs 从文本文件中删除 nul 字符
【发布时间】:2016-12-15 22:46:18
【问题描述】:

我有大约 6MB 大小的文本文件。有些行包含我想删除的 NULL (Chr(0)) 字符。 我有两种方法可以做到这一点:使用 Asc()=0 但这需要大约 50 秒才能完成,另一种方法使用 InStr (line, Chr(0)) =0 (fast ~ 4sec) 但结果会从包含 NULL 字符的行。

以文本文件的第一行为例:

@@MMCIBN.000NULL7NULL076059NULL7653NULL1375686349NULL2528NULL780608NULL10700NULL\NULL_NC_ACT.DIR\CFG_RESET.INI

第一种方法(有效但很慢)

function normalise (textFile )

Set fso = CreateObject("Scripting.FileSystemObject")
writeTo = fso.BuildPath(tempFolder, saveTo & ("\Output.arc"))
Set objOutFile = fso.CreateTextFile(writeTo)
Set objFile = fso.OpenTextFile(textFile,1)

Do Until objFile.AtEndOfStream 
    strCharacters = objFile.Read(1)
    If Asc(strCharacters) = 0 Then
        objOutFile.Write ""
        nul = true
    Else
        if nul = true then
            objOutFile.Write(VbLf & strCharacters)
        else
            objOutFile.Write(strCharacters)
        end if
    nul = false
    End If
Loop

objOutFile.close
end function

输出如下:

@@MMCIBN.000
7
076059
7653
1375686349
2528
780608
10700
\
_NC_ACT.DIR\CFG_RESET.INI

第二种方法代码:

filename = WScript.Arguments(0)

Set fso = CreateObject("Scripting.FileSystemObject")

sDate = Year(Now()) & Right("0" & Month(now()), 2) & Right("00" & Day(Now()), 2)
file = fso.BuildPath(fso.GetFile(filename).ParentFolder.Path, saveTo & "Output " & sDate & ".arc")
Set objOutFile = fso.CreateTextFile(file)
Set f = fso.OpenTextFile(filename)

Do Until f.AtEndOfStream
    line = f.ReadLine

    If (InStr(line, Chr(0)) > 0) Then 
        line = Left(line, InStr(line, Chr(0)) - 1) & Right(line, InStr(line, Chr(0)) + 1)
    end if

    objOutFile.WriteLine line

Loop

f.Close

然后输出是:

@@MMCIBN.000\CFG_RESET.INI

有人可以指导我如何在不丢失信息的情况下快速删除 NULLS。我曾想过尝试使用第二种方法来扫描哪些行号需要更新,然后将其提供给第一种方法以尝试加快速度,但老实说,我什至不知道从哪里开始这样做! 提前谢谢...

【问题讨论】:

  • 你试过Replace()吗?
  • 感谢您的回复。是的,我有,脚本没有输出,但 CPU 和内存使用率很高,仅此而已。

标签: vbscript null


【解决方案1】:

看起来第一种方法只是用换行符替换每个NULL。如果这就是你所需要的,你可以这样做:

更新:

好的,听起来你需要用换行符替换每个 set 的 NULL。让我们试试这个:

strText = fso.OpenTextFile(textFile, 1).ReadAll()

With New RegExp
    .Pattern = "\x00+"
    .Global = True
    strText = .Replace(strText, vbCrLf)
End With

objOutFile.Write strText

更新 2:

我认为TextStream 类的Read/ReadAll 方法在处理文本和二进制数据的混合时遇到了问题。让我们改用ADO Stream 对象来读取数据。

' Read the "text" file using a Stream object...
Const adTypeText = 2

With CreateObject("ADODB.Stream")
    .Type = adTypeText
    .Open
    .LoadFromFile textFile
    .Charset = "us-ascii"
    strText = .ReadText()
End With

' Now do our regex replacement...
With New RegExp
    .Pattern = "\x00+"
    .Global = True
    strText = .Replace(strText, vbCrLf)
End With

' Now write using a standard TextStream...
With fso.CreateTextFile(file)
    .Write strText
    .Close
End With

【讨论】:

  • 第一种方法逐个字符检查,如果我正确理解该方法(我涉足软件,不是专业人士:-))如果前一个字符是 real 然后它为新行提供 VBCrLf,否则将在同一行继续(为了空间和清晰度,我省略了长的 NULL 字符串)我尝试了这种替换方法,但脚本没有输出完全具有高 CPU 使用率和高内存使用率,仅此而已。感谢您迄今为止的帮助...
  • 我明白了。我已经更新了我的答案以寻找 NULL 的 sets 而不是用换行符替换每个实例。看看有没有帮助。
  • 第一行不完整,下一行显示的是111412行!我尝试过的代码如下:textFile = WScript.Arguments(0)Set fso = CreateObject("Scripting.FileSystemObject")writeTo = fso.BuildPath(fso.GetFile(textFile).ParentFolder.Path, saveTo & "Output.arc")Set objOutFile = fso.CreateTextFile(writeTo)strText = fso.OpenTextFile(textFile, 1).ReadAll()With New RegExp`.Pattern = "\x00+"`.Global = True strText = .Replace(strText, vbCrLf)以 objOutFile.Write strText 结尾`
  • 有没有办法改进方法2,If ~ End if 部分?我自己的了解和理解不足以真正改善这一点。我试过 Trim 但这不起作用
  • 参见更新 2。我认为我们需要避免使用Read/ReadAll,因为您的“文本”文件的性质。 更新 2 展示了如何使用 ADO Stream 对象来读取文件。在我的 PC 上使用这种方法读取一个 6 MB 的文件大约需要 5 秒。正则表达式替换和重写总共
【解决方案2】:

我尝试使用此方法 (update2) 来读取 MS-Access 锁定文件(64 字节记录中的空字符终止字符串),并且 ADODB.Stream 不想打开已在使用的文件。所以我把那部分改成了:

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set f = fso.GetFile(Lfile)
    z = f.Size
    set ts = f.OpenAsTextStream(ForReading, 0) 'TristateFalse   
    strLog = ts.Read(z)
    ts.Close
    set f = nothing
    ' replace 00 with spaces
    With New RegExp
        .Pattern = "\x00+"
        .Global = True
        strLog = .Replace(strLog, " ")
    End With
    ' read MS-Access computername and username
    for r = 1 to len(strLog) step 64
        fnd = trim(mid(strLog,r, 32)) & ", " &  trim(mid(strLog,r+32, 32)) & vbCrLf
        strRpt = strRpt & fnd
    next

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-26
    • 2013-03-04
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 2014-12-19
    • 2012-11-05
    相关资源
    最近更新 更多