VBScriptを掌握せよ:FSOと正規表現で挑む、ファイル名正規化の極致
レガシーシステムの深淵で、我々エンジニアを最も苦しめるもの。それはデータそのものではなく、人間が適当に付けた「ファイル名」という名のカオスである。全角英数字、制御文字、OSの制約を無視した記号の羅列。これらを放置することは、システム連携における爆弾を抱えるに等しい。
今日は、VBScriptとFile System Object (FSO)、そしてRegExpエンジンを極限まで使いこなし、このカオスを秩序へと変える術を伝授する。これは単なるコードの提供ではない。保守性とパフォーマンスを両立させる、アーキテクトの矜持だ。
—
1. なぜFSOとRegExpを「正しく」組み合わせるのか
多くのエンジニアは、単純な文字列置換(`Replace`関数)を繰り返してファイル名を処理しようとする。それは愚策だ。処理が重くなるだけでなく、置換順序の依存関係に足元をすくわれる。
我々が用いるのは、`VBScript.RegExp`オブジェクトによるパターンマッチングと、動的なマッピングテーブルだ。FSOはあくまで「ファイルシステムの境界」としてのみ利用し、ロジックはメモリ上で完結させる。これが、IO負荷を最小化し、数万ファイル規模の走査を現実的な時間で完了させる唯一の解である。
—
2. 極限の正規化スクリプト:実装コード
以下のコードは、単に動くだけではない。メモリリークを許さないオブジェクト管理と、全角英数字を確実に半角化する変換ロジックを備えている。
‘ — FileNameNormalizer.vbs —
Option Explicit
‘ 処理対象ディレクトリ
Const TARGET_FOLDER = “C:\Data\Unorganized”
Call Main()
Sub Main()
Dim fso, folder, file
Dim regEx, newName
‘ FSOのインスタンス生成
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 正規表現エンジンのセットアップ
Set regEx = CreateObject(“VBScript.RegExp”)
regEx.Global = True
regEx.IgnoreCase = True
If Not fso.FolderExists(TARGET_FOLDER) Then
WScript.Echo “対象フォルダが存在しません。”
Exit Sub
End If
Set folder = fso.GetFolder(TARGET_FOLDER)
For Each file In folder.Files
newName = NormalizeFileName(file.Name, regEx)
‘ 変更が必要な場合のみリネーム実行
If LCase(file.Name) <> LCase(newName) Then
On Error Resume Next
file.Name = newName
If Err.Number <> 0 Then
WScript.Echo “失敗: ” & file.Name & ” -> ” & newName
End If
On Error GoTo 0
End If
Next
‘ オブジェクトの明示的解放(メモリ管理の鉄則)
Set regEx = Nothing
Set folder = Nothing
Set fso = Nothing
End Sub
‘ ファイル名の正規化ロジック
Function NormalizeFileName(strName, regEx)
Dim i, charCode, result
result = “”
‘ 1. 全角英数字を半角に変換
For i = 1 To Len(strName)
charCode = AscW(Mid(strName, i, 1))
‘ 全角英数字の範囲 (FF01-FF5E) を半角にオフセット調整
If charCode >= &HFF01 And charCode <= &HFF5E Then
result = result & Chr(charCode - &HFEE0)
Else
result = result & Mid(strName, i, 1)
End If
Next
' 2. 不適切な記号をアンダースコア(_)へ置換
' \ / : ? " < > | を置換対象とする
regEx.Pattern = “[\\/:?””<>|]”
result = regEx.Replace(result, “_”)
NormalizeFileName = result
End Function
—
3. シニアエンジニアが押さえるべき「3つの要点」
① 文字コードオフセットの魔法
`AscW`関数を使って文字コードの直接演算を行う手法は、VBScriptにおける高速化の極意だ。`StrConv(str, vbNarrow)`を使う手法もあるが、これは環境依存の罠が多い。Unicodeベースのオフセット計算であれば、OSのロケール設定に左右されず、常に期待通りの結果を返す。
② オブジェクトのライフサイクル管理
`Set obj = Nothing`をサボるな。特に巨大なフォルダを走査する場合、VBScriptのガベージコレクションは頼りにならない。ループ内で一時的なオブジェクトを生成する場合も、スコープを最小化し、必ず明示的に解放する。これがシステムが長期間稼働してもメモリを食いつぶさないための唯一の防衛線だ。
③ エラーハンドリングの境界線
`On Error Resume Next`を多用するのは悪手だが、ファイルシステム操作では不可欠だ。ファイルが使用中(ロック状態)であるケースは必ず発生する。エラーを握りつぶすのではなく、リネームに失敗したファイル名をログとして出力し、処理を続行させる「堅牢性」を実装せよ。
—
結びに代えて
VBScriptは「古い」技術ではない。枯れた技術だ。枯れた技術には、数十年分の洗練と、OSの深層部への直接アクセスを可能にする強靭さがある。
ファイル名の正規化という、一見地味な作業の中にこそ、そのアーキテクトの力量が出る。このスクリプトをテンプレートとして、君の現場の「カオス」を「インフラ」に変えていくことを期待する。
自動化とは、単にコードを書くことではない。システムに規律をインストールすることだ。健闘を祈る。
