web-dev-qa-db-ja.com

VBSで1行ごとにtxtファイルを読み取る

私はこのコードを試しています:

filename = "test.txt"
listFile  = fso.OpenTextFile(filename).ReadAll
listLines = Split(listFile, vbCrLf)
For Each line In listLines
   WScript.Echo line 
   'My Stuff
Next

またはこの他:

filename = "test.txt"
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set f = fso.OpenTextFile(filename, ForReading)
    Do Until f.AtEndOfStream
      myLine = f.ReadLine
      WScript.Echo myLine
      'My Stuff
    Loop

どちらの場合も、一度にすべての行がエコーされるのはなぜですか?もちろん、行ごとに作業することはできませんか?何か案が?

9
Mark

ファイルに面白いEndOfLineマーカーが含まれています。行がvbLfで終了しているとしましょう:

>> fn = "lf.txt"
>> goFS.CreateTextFile(fn).Write Replace("a b c ", " ", vbLf)
>> set ts = goFS.OpenTextFile(fn)
>> do until ts.AtEndOfStream
>>    WScript.Echo ts.ReadLine
>> loop
>>
a
b
c

ご覧のとおり、.ReadLineはvbLf(UNIX)に対応できます。ただし、.ReadAll()のSplit()は失敗します。

>> t = goFS.OpenTextFile(fn).ReadAll()
>> a = Split(t, vbCrLf)
>> WScript.Echo UBound(a)
>> WScript.Echo a(0)
>>
0
a
b
c

tには単一のvbCrLfが含まれていないため、 Split() は、tを単一の要素として含むUBound()== 0の配列を返します。 。少なくとも3(4)行のように見えるエコー。行の配列が本当に必要な場合は、vbLfでSplit()を使用できます。

しかし、ファイルにvbLfの末尾が含まれている場合、.ReadLineループは正常に機能するはずです。

.ReadLine()はvbCr(mac)に対応できません:

>> fn = "cr.txt"
>> goFS.CreateTextFile(fn).Write Replace("a b c ", " ", vbCr)
>>
>> set ts = goFS.OpenTextFile(fn)
>> do until ts.AtEndOfStream
>>    WScript.Echo ts.ReadLine
>> loop
>>
c

B + crはa + crを「上書き」し、c + crによって「上書き」されます。セパレーターとしてvbCrを使用しない限り、.ReadAll()アプローチも失敗します。

しかし、ファイルにvbCrの末尾が含まれている場合、どのスニペットも「一度にすべての行をエコー」することはできません。

あなたのファイルは宇宙から来ていますか?

コメントを更新:

Filesystemobjectを使用してUTF-8を読み取る はできません。ファイルをUTF-16に変換し、.OpenTextFileのときにformatパラメーターのUnicodeオプションを使用するか、またはADODBストリームを操作します。

どのEOLマーカーが使用されているかを知ることは、まだ興味深いでしょう。

11
Ekkehard.Horner

コードは正常に動作しているようです。行が実際には行ごとに読み取られることを示すために、少し変更しました。

Set fso=CreateObject("Scripting.FileSystemObject")

filename = "test.txt"
listFile = fso.OpenTextFile(filename).ReadAll
listLines = Split(listFile, vbCrLf)
i = 0

For Each line In listLines
   WScript.Echo CStr(i) + " : " + line 
   i = i + 1

   'My Stuff
Next

fsoがスクリプトのどこかに設定されていると思いますが、完全を期すために、この追加の行を追加しました。

入力ファイルが実際にvbCrLfで区切られた複数の行を持っていることを確認する必要があります。カウンターiは、行の読み取り中に行インデックスを表示するため、各行のデバッグに役立ちます。

3
xxbbcc