
TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。
詳細情報
| • | |
| • | |
| • |
![]()
Scripting Guy さん、よろしくお願いします。各行の終わりに不要なタブ文字がある 5,000 個以上のテキスト ファイルを持っています。この不要なタブ文字を削除するスクリプトを記述する方法はありますか。
-- TT

注 : 今回の Hey, Scripting Guy! コラムがいつもと少し違っているように見える (思える) のでしたら、それには十分な理由があります。それは、本当にいつもの Hey, Scripting Guy! コラムと少し違っているからです。2007 年 10 月 8 日のコラムとして公開する予定だったコラムは、サードパーティ企業について言及したために (お世辞でも、言及は言及です) 削除しなければなりませんでした。記事を "手直し" するという選択肢もあったのですが、コラムを全部書き直さない限り手直しは絶対に不可能でした。したがって、今日のコラムはコードとコードの説明だけを掲載して終わりにすることにしました。私たちがこのコラムをお届けするのを楽しんだのと同じくらい、このコラムを楽しんでいただければさいわいです。 |
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForReading)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If Right(strLine, 1) = Chr(9) Then
intLength = Len(strLine)
strLine = Left(strLine, intLength - 1)
strContents = strContents & strLine & vbCrLf
End If
Loop
objFile.Close
Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForWriting)
objFile.Write strContents
objFile.Close
このスクリプトの冒頭では、テキスト ファイルに関する多くのスクリプトの冒頭部分と同様に、テキスト ファイルを開く際に使用する 2 つの定数 (ForReading と ForWriting) を定義しています。定数を定義したら、次のように Scripting.FileSystemObject のインスタンスを作成し、OpenTextFile メソッドを使用して読み取り用に C:\Scripts\Test.txt ファイルを開きます。
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForReading)
ファイルを開いたら、ファイルの AtEndOfStream プロパティが True になるまで実行する Do Until ループを設定します (簡単に言うと、ファイル全体を読み取るまでループ処理を続けます)。このループ処理では、ReadLine メソッドを使用してファイルの 1 行目を読み取り、その値を strLine という名前の変数に格納します。
strLine = objFile.ReadLine
では、次の行に移りましょう。
If Right(strLine, 1) = Chr(9) Then
TT さんによればテキスト ファイルのすべての行の最後に不要なタブ文字が 1 つあるそうですが、ここでは上記のコード行を使用して、指定した行の最後にタブ文字があるかどうか確認することにしました。では、どのような方法で実行するのでしょうか。Right 関数を使用して、文字列の最後の文字を調べます。この文字が ASCII 値の 9 なら、タブ文字で間違いありません。つまり、削除する必要がある文字です。
では、文字列の最後からこの不要なタブ文字を削除するにはどうしたらよいでしょうか。まず、Len 関数を使用して文字列の文字の総数を特定し、その値を intLength という名前の変数に格納します。次に、Left 関数を使用して、最後の 1 文字を除くすべての文字 (これが intLength – 1 という構文が表すものです) を取得します。たとえば文字列が cat だとします。文字列の長さ (文字の総数) は 3 です。この長さから 1 を引くと・・・。ええと、ちょっと待ってください。2 です。したがって、文字列の先頭から数え始めて最初の 2 文字を取得すれば、新しい文字列は ca になります。
念のため、この部分の処理について混乱された場合に備えてお伝えしました。
その後、次のコード行を使用して、変更した文字列値 (および復帰改行文字) を strContents という名前の変数に追加します。
strContents = strContents & strLine & vbCrLf
その後ループの先頭に戻り、テキスト ファイルの次の行に対して同じ処理を繰り返して、不要なタブ文字を削除し、変更した行を strContents 変数値の末尾に追加します。この後は同様の作業を繰り返します。
ループ処理が完了すると、不要なタブ文字がすべて削除された、新しいバージョンのテキスト ファイルがメモリ内に作成されます。この新しいバージョンを実際のファイル自体 (C:\Scripts\Test.txt) に書き戻すには、まずファイルを閉じ、次に OpenTextFile メソッドを使用して今度はファイルを書き込み用に再び開く必要があります。
Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForWriting)
ファイルを開いたら、Write メソッドを使用してファイルの新しいバージョンを Test.txt に書き込みます。これが完了したら、Close メソッドを呼び出して最後にファイルを閉じ、作業完了です。
良い質問ですね。どうして Replace 関数を使用してすべてのタブ文字を置き換えないのか、ですって。そうすることもできましたが、1 つだけ問題があります。ファイル内に削除するべきではない他のタブ文字が存在する可能性があります。Replace 関数を使用すると "すべて" のタブ文字が削除されますが、今回紹介した方法では行末にあるタブ文字だけが削除されます。
この話題に関して言えば、末尾に複数の不要なタブ文字が存在する行もあり得ます。行末の複数のタブ文字を削除することはできるか、ですって。もちろんです。以下に、2 つ目の Do Until ループを備えた、変更した Do Until ループを紹介します。この 2 つ目のループでは、文字列の最後の文字を確認し、この文字がタブ文字の場合は削除します。次に、変更した文字列の最後の文字を確認し、タブ文字の場合は削除します。この処理は、行末のタブ文字をすべて削除するまで続きます。
変更したコードは次のとおりです。
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
Do Until i = 100
If Right(strLine, 1) = Chr(9) Then
intLength = Len(strLine)
strLine = Left(strLine, intLength - 1)
Else
Exit Do
End If
Loop
strContents = strContents & strLine & vbCrLf
Loop