【入門編】【実務中級者向け】FSOで読み込んだテキスト内の「無駄な連続空行」を単一空行へ整形・圧縮するテキストクレンジング – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク
スポンサーリンク

乱雑なログを、美しい秩序へ。VBScriptのFSOを極めて「テキストクレンジング」を自動化する

こんにちは。現場の自動化を支えるアーキテクトです。

業務を自動化していると、避けては通れない壁があります。それは「データの汚れ(Dirty Data)」です。
システムが出力したログファイルや、誰かが手作業で編集したテキストデータ。それらの中に、意味もなく連続する空行が大量に含まれていたらどうでしょうか?

「たかが空行」と思うかもしれません。しかし、数万行に及ぶログを解析する際、その「無駄な空白」は可読性を著しく下げ、検索性や解析スピードを阻害するノイズとなります。

今日は、そんなノイズを鮮やかに削ぎ落とし、テキストを「正規化(クレンジング)」する技術を伝授しましょう。VBScriptの強力な武器である FileSystemObject (FSO) を使いこなし、単なる「書き換え」ではない、プロフェッショナルな「整形」のロジックを構築していきます。

ここをクリアすれば、VBScriptの基本はバッチリですよ。さあ、始めていきましょう。

1. 武器を手に入れる:FileSystemObject (FSO) とは?

VBScript単体では、ファイルを開いたり、中身を読み書きしたりする能力は限定的です。そこで登場するのが FileSystemObject (FSO) です。

FSOは、Windowsのファイルシステムを操作するための「司令塔」のようなオブジェクトです。

  • ファイルが存在するか?
  • フォルダの中に何があるか?
  • ファイルの中身を1行ずつ読み込むにはどうすればいいか?

これら全ての問いに答えてくれる、自動化エンジニアにとっての「生命線」と言える存在です。

重要なオブジェクトのライフサイクル

FSOを扱う上で、最も大切なのは「オブジェクトの生成と破棄」です。
VBScriptでは `Set` キーワードでオブジェクトを生成しますが、使い終わったら `Nothing` を代入してメモリから解放するという作法があります。これを怠ると、ファイルが「他のプロセスによって使用中」としてロックされ、プログラムが止まってしまう原因になります。

2. アルゴリズムの設計:どうやって「連続空行」を見抜くか?

今回やりたいことは、「連続する空行を、1行の空行に圧縮する」ことです。
これを実現するために、単純な「全置換」ではなく、「状態を管理する(ステートフルな)」ロジックを組みます。

思考のプロセス

1. ファイルを1行ずつ読み進める。
2. 今読んでいる行が「空行」かどうかを判定する。
3. ここが肝心: 「直前の行も空行だったか?」という記憶(フラグ)を持っておく。

  • もし「今も空行」かつ「直前も空行」なら $\rightarrow$ 無視する(書き込まない)
  • もし「今が空行」かつ「直前は文字があった」なら $\rightarrow$ 1行だけ書き込む
  • もし「今、文字がある」なら $\rightarrow$ そのまま書き込む

この「直前の状態を覚えておく」という考え方が、プログラミングにおける「状態管理」の第一歩です。

3. 実装:テキストクレンジング・スクリプト

では、実際に動作するコードを見てみましょう。このコードは、そのまま `.vbs` ファイルとして保存して実行できるレベルまで磨き上げてあります。

' ==========================================================================
' Script Name: TextCleaner.vbs
' Description: テキスト内の連続する空行を、単一の空行に圧縮する
' Author: Legendary Architect
' ==========================================================================

Option Explicit ' 変数の宣言を強制(バグを防ぐための鉄則です)

' --- 設定セクション ---
Dim strInputFile, strOutputFile
strInputFile  = "input_log.txt"   ' 読み込み元ファイル名
strOutputFile = "cleaned_log.txt" ' 書き出し先ファイル名

' --- メイン処理 ---
Call Main()

Sub Main()
    Dim fso, objInputFile, objOutputFile
    Dim strLine, strLastLineContent
    Dim blnIsLastLineEmpty
    
    ' FileSystemObjectの生成
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    ' 入力ファイルの存在確認(これがないとエラーで即死します)
    If Not fso.FileExists(strInputFile) Then
        MsgBox "エラー: 入力ファイル '" & strInputFile & "' が見つかりません。", vbCritical
        Exit Sub
    End If

    ' ファイルを開く (ForReading: 読み取り専用)
    Set objInputFile = fso.OpenTextFile(strInputFile, 1)
    ' 書き出し用ファイルを作成 (True: 上書き許可)
    Set objOutputFile = fso.CreateTextFile(strOutputFile, True)

    ' 状態管理用の初期化
    ' 「直前の行が空だったか」を管理するフラグ
    blnIsLastLineEmpty = False

    ' ファイルの終端に達するまで1行ずつループ
    Do Until objInputFile.AtEndOfStream
        strLine = objInputFile.ReadLine
        
        ' Trim関数で、スペースやタブだけの行も「空行」として扱う
        ' これが実務における「データの綺麗さ」へのこだわりです
        If Trim(strLine) = "" Then
            ' 【判定】今読んでいる行が空行の場合
            If Not blnIsLastLineEmpty Then
                ' 直前の行が空行でなければ、この1行だけを書き込む
                objOutputFile.WriteLine ""
                blnIsLastLineEmpty = True ' 「今、空行を書き込んだ」という状態にする
            End If
            ' 直前も空行だった場合は、何もしない(=圧縮される)
        Else
            ' 【判定】今読んでいる行に文字がある場合
            objOutputFile.WriteLine strLine
            blnIsLastLineEmpty = False ' 「文字があった」という状態に戻す
        End If
    Loop

    ' --- 後処理(クリーンアップ) ---
    ' オブジェクトを閉じ、メモリを解放する。これは「儀式」として必ず行いましょう
    objInputFile.Close
    objOutputFile.Close
    
    Set objInputFile = Nothing
    Set objOutputFile = Nothing
    Set fso = Nothing

    MsgBox "クレンジングが完了しました!" & vbCrLf & "出力先: " & strOutputFile, vbInformation
End Sub

4. アーキテクトの視点:陥りやすい罠と、プロの工夫

このコードを読み解くとき、単に「動くからOK」で終わらせてはいけません。設計の意図を理解することが、中級者への道です。

① `Trim(strLine)` の重要性

実務のログファイルには、一見空行に見えて「半角スペースが3つ入っているだけ」という行が多々あります。単に `strLine = “”` と比較してしまうと、これらは「文字がある行」と判定され、空行の圧縮に失敗します。`Trim` を使って、前後の空白を削ぎ落としてから判定するのが、現場で通用する「堅牢なコード」です。

② メモリ効率への配慮

もし、ファイル全体を一度にメモリに読み込む `ReadAll` メソッドを使ってしまったらどうなるでしょうか? 数GB(ギガバイト)のログファイルを読み込んだ瞬間、PCのメモリは枯渇し、システムはクラッシュします。
今回のように `ReadLine` で「1行ずつ処理する」手法は、ファイルサイズがどれほど巨大になっても、メモリ消費を一定に抑えられる非常に優れた設計です。

③ オブジェクトの解放(ライフサイクル管理)

コードの最後にある `Set … = Nothing`。これ、面倒に感じませんか?
しかし、WindowsというOSにおいて、ファイルは「開いている間、誰にも触らせない」というロック状態になります。スクリプトが終了してもオブジェクトがメモリに残っていると、次にそのファイルを開こうとしたときに「使用中です」というエラーに遭遇することになります。「使い終わったら、責任を持って片付ける」。これがプロの作法です。

まとめ:次の一歩へ

いかがでしたか?
一見シンプルに見える「空行の圧縮」ですが、その裏には状態管理、メモリ効率、堅牢な判定、そしてリソースの解放という、自動化エンジニアに求められるエッセンスが凝縮されています。

VBScriptは古い言語だと言われることもあります。しかし、Windows環境において、これほど素早く、強力にOSの機能を操れる言語も他にありません。

「マクロの記録」から一歩踏み出し、今回のような「ロジック」を組み立てられるようになれば、あなたの自動化スキルは飛躍的に向上します。

ここをクリアすれば、VBScriptの基本はバッチリですよ。
次は、もっと複雑なデータ解析に挑戦してみましょう。応援しています!

タイトルとURLをコピーしました