【実務・中級編】【改行コード整形】CRLF / LF / CR が混在するテキストファイルをFSOで標準化(CRLF変換)するスクリプト – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

【VBScript極意】混在する改行コードを制する。FSOによる「完全なる標準化」の実装術

現場の自動化において、最も地味で、かつ最も多くのシステム障害を引き起こす元凶。それは「改行コードの不一致」だ。

Linuxから吐き出された `LF`、古のMacを引きずる `CR`、そしてWindowsの `CRLF`。これらが混在したテキストファイルを、何も考えずに `ReadLine` して `WriteLine` するだけのコードで処理しようとしていないか? もしそうなら、あなたのツールは「時限爆弾」を抱えているに等しい。

今日は、FSO(FileSystemObject)を駆使し、あらゆる異物混入を許さない「堅牢な改行コード標準化エンジン」の設計思想と実装を授ける。

—

1. なぜ「ReadLine」一発ではダメなのか

多くのエンジニアが犯す最大の過ちは、`TextStream.ReadLine` をループさせるだけのコードだ。
`ReadLine` は「CR, LF, CRLF」を自動的に認識して削除するが、出力時に自動でCRLFを付与するという仕様がある。これが災いし、読み込み時に元の改行コードが何だったのかという情報が完全に失われる。

さらに恐ろしいのは、「読み込み時に改行として認識されない特殊なバイト列」や、「ファイルの末尾が改行で終わっていない場合」の挙動だ。これらを放置すれば、後続のデータベース投入処理やCSVインポートで致命的なエラーを引き起こす。

—

2. 堅牢な設計へのアプローチ:ストリームの直視

我々が目指すべきは、「読み込み」と「書き込み」を完全に分離し、改行コードを一度「標準化」した上で再構成するアプローチだ。

プロダクションコード:NormalizeLineEndings.vbs

このスクリプトは、入力ファイルの文字コードを判定し、改行コードをWindows標準(CRLF)に統一して書き出す。

Option Explicit

‘ —————————————————————————
‘ 関数: NormalizeLineEndings
‘ 目的: 任意の改行コードが混在するファイルを読み込み、CRLFのみに変換して保存
‘ —————————————————————————
Sub NormalizeLineEndings(strInputPath, strOutputPath)
Dim objFSO, objFile, strContent
Set objFSO = CreateObject(“Scripting.FileSystemObject”)

‘ 1. バイナリモードではなくテキストモードで開く(まずはメモリへ)
‘ 大規模ファイルの場合はここをストリーム分割読み込みにする必要があるが、
‘ 一般的な業務データなら一旦メモリに乗せるのが最もバグが少ない
Set objFile = objFSO.OpenTextFile(strInputPath, 1, False)
strContent = objFile.ReadAll
objFile.Close

‘ 2. 正規表現による置換で改行コードを正規化
‘ LF(Chr(10))およびCR(Chr(13))を一度すべてCRLFに置換し、
‘ 重複したCRを削除することで、混在環境を完全に無効化する
Dim objRegEx
Set objRegEx = New RegExp
objRegEx.Global = True

‘ まず、すべてのLFをCRLFに変換
objRegEx.Pattern = “\r\n|\n|\r”
strContent = objRegEx.Replace(strContent, vbCrLf)

‘ 3. 出力処理
‘ WriteLineを使用せず、Writeで書き出すことで、意図しない改行追加を防ぐ
Dim objOutFile
Set objOutFile = objFSO.CreateTextFile(strOutputPath, True)
objOutFile.Write strContent
objOutFile.Close

Set objRegEx = Nothing
Set objFSO = Nothing
WScript.Echo “処理完了: ” & strOutputPath
End Sub

‘ 使用例
NormalizeLineEndings “C:\data\input.txt”, “C:\data\output_normalized.txt”

—

3. 実務で「生き残る」ための3つの鉄則

このコードをそのまま現場に投入する際、以下の3点だけは意識しておいてほしい。

① 大容量ファイルへの対応(メモリ管理)

上記のコードは `ReadAll` を使用している。これはファイルサイズが数MB程度であれば高速だが、数GBに及ぶログファイルを扱う場合はメモリを圧迫する。その場合は `ReadLine` でバッファリングしつつストリームを生成する設計に切り替える必要があるが、まずは「メモリに載るサイズ」であることを前提に、処理速度と堅牢性のバランスを取るのが正解だ。

② 文字コードの闇(BOM問題)

`OpenTextFile` は、文字コードを明示的に指定しない場合、OSのデフォルト(主にShift-JIS)として開く。もしUTF-8(BOMなし)のファイルを扱う場合は、`ADODB.Stream` オブジェクトを使用して、エンコーディングを明示的に `utf-8` に設定して読み込む必要がある。FSOは便利な反面、Unicodeの扱いは非常に繊細だ。

③ エラーハンドリングは「呼び出し元」で行え

このスクリプトは汎用パーツとして設計している。ファイルがロックされている、パスが存在しない、といったIOエラーは、関数内で `On Error Resume Next` で誤魔化さず、呼び出し元のメイン処理で捕捉せよ。それが「保守性の高いコード」の絶対条件だ。

—

最後に:エンジニアとしての矜持

「動けばいい」というコードは、数ヶ月後の自分を苦しめる呪いになる。
今回紹介した「正規表現を用いた改行の置換」は、一見遠回りに見えるかもしれない。しかし、複雑な改行の組み合わせをロジックで追いかけるよりも、「一度すべてをCRLFに置換する」という圧倒的な力技の方が、結果としてバグの入り込む余地を限りなくゼロにする。

VBScriptは古い言語かもしれない。だが、その仕様を深く理解し、泥臭いファイル処理を洗練されたアルゴリズムで解決する。それこそが、伝説的な自動化エンジニアの歩む道だ。

さあ、このスクリプトをあなたの武器に加え、現場の無秩序なファイルを一掃してやってくれ。

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