バッチファイル(.bat)で日本語が「???」や「ã‚‚ã—ã‚…」のように化ける原因の多くは、
ファイルの保存エンコーディングとコンソールのコードページが一致していないことにあります。
Windowsの cmd.exe は既定で Shift‑JIS 系(ACP/OEM 932)を前提として動作しますが、
近年は UTF‑8 のファイルや出力と混在しがちです。ここでは「どこが UTF‑8/どこが Shift‑JIS なのか」を切り分け、
実務で安全に文字化けを防ぐ手順をまとめます。
現状の切り分け:コードページとファイルの保存形式を確認する
まず現在のコンソールのコードページを chcp
で確認します。932 なら Shift‑JIS、65001 なら UTF‑8 です。
chcp
次に、編集している .bat や .txt が「ANSI(SJIS)」か「UTF‑8(BOM 有/無)」かをエディタで確認します。
.bat を UTF‑8 BOM 付きで保存すると、先頭の BOM がコマンドとして解釈されてエラーになることがあるため要注意です。
バッチファイル本文の日本語が化ける/エラーになるときの対処
バッチ自体に日本語リテラル(echo こんにちは
等)を含める場合は、最もトラブルが少ないのは
「ファイルは Shift‑JIS(ANSI)で保存し、コンソールは 932 のまま使う」方針です。
すでに UTF‑8 で保存しているなら、BOM 付きは避け、ASCII のみで記述し、日本語の出力は外部ファイルや PowerShell 経由に逃がすのが堅実です。
@echo off
rem 日本語は外部から供給(後述の PowerShell 例)
コンソールを一時的に UTF‑8 に切り替えて使う(出力中心の用途)
UTF‑8 テキストを正しく表示したいだけなら、処理の前後でコードページを 65001 に切り替え、最後に元へ戻す手順が使えます。
ただしレガシーなコマンドの一部は 65001 で動作が不安定になる場合があるため、スコープを限定して使います。
@echo off
setlocal
for /f "tokens=2 delims=: " %%A in ('chcp ^| find ":"') do set "_origCP=%%A"
chcp 65001 >nul
rem ここで UTF-8 のファイル表示などを実施
type utf8.txt
chcp %_origCP% >nul
endlocal
UTF‑8 のファイルを「読む」必要があるときの安全策
for /f
は基本的に ANSI 前提であり、UTF‑8 の行単位処理は苦手です。
確実に処理したい場合は PowerShell に委譲するとエンコーディングを明示できます。
@echo off
for /f "usebackq delims=" %%L in (`powershell -NoProfile -Command "Get-Content -Encoding UTF8 -Path 'C:\work\utf8.txt'"`) do (
echo %%L
)
UTF‑8 で「書き出し」たいときの安全策
> out.txt
のリダイレクトは通常、現在のコードページに依存します。
生成ファイルを UTF‑8 に固定したいなら、PowerShell の Set-Content
を呼び出すのが簡単です。
@echo off
set "MSG=こんにちは、世界"
powershell -NoProfile -Command ^
"$s = [Console]::InputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new(); " ^
"$text = '%MSG%'; Set-Content -Path 'C:\work\out.txt' -Value $text -NoNewline -Encoding UTF8"
.bat 自体は ASCII に徹し、日本語は外部ファイルで管理する設計
長期安定運用を重視するなら、.bat は ASCII のみで記述し、日本語メッセージは
「UTF‑8 の .txt を PowerShell で読み込んで表示」する方式に分離すると、編集者や実行環境が変わっても化けにくくなります。
@echo off
powershell -NoProfile -Command "Get-Content -Path 'C:\work\msg_ja.txt' -Encoding UTF8 | Write-Host"
リダイレクトの落とし穴(cmd /U と UTF‑16LE)
cmd /U
を使うと、パイプやリダイレクトの出力が UTF‑16LE になります。
下流ツールが UTF‑16LE を想定している場合は有効ですが、意図せず混在させると別の文字化けを招きます。
生成物のエンコーディングを決め、全行程で統一することが重要です。
cmd /u /c "echo こんにちは > C:\work\utf16.txt"
Windows 特有の設定に頼りすぎない(システムロケールの UTF‑8)
地域の設定にある「ベータ版:世界対応のために Unicode UTF‑8 を使用」にチェックを入れると、
システムの非 Unicode アプリ互換に影響し、既存バッチや一部アプリが予期せず振る舞いを変える場合があります。
開発・検証環境以外では安易に有効化しない方が安全です。
最小トラブルで運用する指針
バッチ本文の文字は原則 ASCII に限定し、.bat の保存は Shift‑JIS(ANSI)に統一するのが保守しやすい選択です。
UTF‑8 の資産とやり取りする場合に限り、処理の直前直後のみ chcp 65001
を使うか、読み書きは PowerShell に任せてエンコーディングを明示します。
BOM 付き UTF‑8 の .bat は避け、BOM なしでも非 ASCII を混ぜない方針にすると事故が激減します。
チェックリスト:化けたらここを確認
いまのコンソールのコードページが 932 か 65001 か。編集している .bat/.txt の保存形式が SJIS か UTF‑8 か。.bat に BOM が付いていないか。
for /f
で UTF‑8 を無理に読もうとしていないか。リダイレクトで意図しないコードページのファイルを作っていないか。
これらを順に抑えるだけで、ほとんどの文字化けは解決できます。