背景
サーバーログの解析で「ERRORとWARNを同時に、行番号付きで抽出したい」というニーズに対し、VSCode標準の検索機能(Ctrl+F)は1パターンしか扱えず、行番号の記録も手動でした。複数パターン一括抽出マクロの実装ポイントを紹介します。
1. 選択範囲をパターンリストとして読み取る
function getSelectedPatterns(
document: vscode.TextDocument,
selection: vscode.Selection
): string[] {
const patterns: string[] = [];
for (let i = selection.start.line; i <= selection.end.line; i++) {
const lineText = document.lineAt(i).text.trim();
if (!lineText || lineText.startsWith('#') || lineText.startsWith('//')) {
continue;
}
try {
new RegExp(lineText);
patterns.push(lineText);
} catch (e) {
vscode.window.showWarningMessage(`不正な正規表現をスキップ: ${lineText}`);
}
}
return patterns;
}
複数行を選択した状態でマクロを実行すると、各行を1つの正規表現パターンとして扱います。#や//で始まる行はコメントとしてスキップし、new RegExp(lineText)が例外を投げた行(構文的に不正な正規表現)も自動的に除外することで、パターンリストをテキストファイルとして管理・再利用しやすくしています。
2. 全行を1回ずつスキャンして行番号付きで記録
for (const pattern of patterns) {
const regex = new RegExp(pattern);
const matchedLines: MatchedLine[] = [];
for (let i = 0; i < document.lineCount; i++) {
const line = document.lineAt(i);
if (regex.test(line.text)) {
matchedLines.push({ lineNumber: i + 1, text: line.text });
}
}
matches.push({ pattern, lines: matchedLines });
}
document.lineAt(i)で1行ずつ取得しregex.test()で判定するだけの単純な実装ですが、行番号をi + 1(1-based)で保持しておくことで、抽出結果から元ファイルへCtrl+Gでジャンプする際に迷わなくなります。パターン数×行数のループになるため計算量はO(パターン数×行数)ですが、数千行程度のログなら体感上問題ありません。
3. 行番号の桁揃えで視認性を上げる
const maxLineNumber = Math.max(...match.lines.map(l => l.lineNumber));
const lineNumberWidth = String(maxLineNumber).length;
match.lines.forEach(matchedLine => {
const lineNumberStr = String(matchedLine.lineNumber).padStart(lineNumberWidth, ' ');
lines.push(`[Line ${lineNumberStr}] ${matchedLine.text}`);
});
マッチした行番号の最大値から桁数を求め、padStartで全行番号を右寄せに揃えることで、[Line 5]と[Line 389]のように出力が縦に整列します。小さな工夫ですが、大量の抽出結果を目視で追う際の可読性が変わります。
4. 出力は新規ドキュメントとして隣に開く
const doc = await vscode.workspace.openTextDocument({
content: output,
language: 'log'
});
await vscode.window.showTextDocument(doc, {
viewColumn: vscode.ViewColumn.Beside,
preview: false
});
ViewColumn.Besideを指定するだけで、元ファイルの隣のペインに抽出結果が開きます。元ファイルを一切変更せず、抽出結果は別ファイルとして保存できるため、調査の履歴を残しながら安全に作業できます。
まとめ
選択範囲を「パターンリスト」として解釈する発想と、行番号の記録・桁揃えによる可読性向上、この2点が実務で使えるログ抽出ツールにする上でのポイントでした。カンマ区切り入力への対応を含む完全なコードは元記事にまとめています。