2014-08-28 103 views
2

我擁有大小約爲6MB的文本文件。有一些行包含我想刪除的NULL(Chr(0))字符。 我有兩種方法來做到這一點:使用Asc()= 0,但這大約需要50s完成,另一種方法使用InStr(行,Chr(0))= 0(快約4秒),但結果刪除重要信息包含NULL字符的行。使用vbs從文本文件中刪除nul字符

文本文件作爲例子的第一行:

@@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 

是否有人可以指導我如何快速去除空值,而不會丟失信息。我曾嘗試使用第二種方法來掃描哪些行號需要更新,然後將其提供給第一種方法來嘗試加快速度,但老實說,我不知道哪裏可以開始做這件事! 在此先感謝...

+0

您試過['Replace()'](http://msdn.microsoft.com/en-us/library/238kz954(v = vs.84).aspx )? – 2014-08-28 18:14:45

+0

感謝您的回覆。是的,腳本沒有輸出,但具有較高的CPU和內存使用率,就是這樣。 – BertB 2014-08-28 18:39:40

回答

3

它看起來像第一種方法是用換行符替換每個NULL。如果這是你所需要的,你可以這樣做:

更新時間:

OK,聽起來像是你需要更換每個設置的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 
+0

第一種方法檢查字符,如果我正確地理解方法(我涉及到軟件,而不是一個職業:-))NULL被替換爲「」,如果前一個字符是*真實*然後它給VBCrLf一個新的行,否則將繼續在同一行(我遺漏了空字符和清晰度的NULL長字符串)我試過這個替換方法,但沒有輸出從腳本根本高CPU使用率和高內存使用情況,這就是它。感謝您的幫助到目前爲止... – BertB 2014-08-28 18:34:58

+0

我明白了。我更新了我的答案,以查找NULL的_sets_而不是用換行符替換每個實例。看看是否有幫助。 – Bond 2014-08-28 19:03:50

+0

第一行不完整,下一行顯示實際行111412!我試過的代碼如下:'textFile = WScript.Arguments(0)' 'Set fso = CreateObject(「Scripting.FileSystemObject」)' 'writeTo = fso.BuildPath(fso.GetFile(textFile) .ParentFolder.Path,saveTo& 「Output.arc」)'' 設置objOutFile = fso.CreateTextFile(的writeTo)'' = strText中fso.OpenTextFile(文本文件,1).ReadAll()' '隨着新RegExp' '.Pattern = 「\ X00 +」' 。全球=真 strText中= .Replace(strText中,vbCrLf) 完隨着 objOutFile.Write strText' – BertB 2014-08-28 19:32:29

1

我試圖用於讀取MS-訪問鎖定文件這種方法(UPDATE2)(空字符終止於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