こんにちは。いーかです。
この記事では、Windowsで「このファイル、BOM付いてる?」を PowerShellだけで確実に確認する方法をまとめます。
CSV/JSON/TXTなど、UTF-8テキスト全般にそのまま使えます。
⚠️ 注意:PowerShell 5.1は“環境差”と“.ps1文字化け”がある(最初にここだけ)
PowerShellは バージョンによって使える引数や挙動が違うことがあります。
実際に私の環境(Windows PowerShell 5.1)では、次の地雷がありました。
-
Get-Content -AsByteStreamが 存在しない -
Format-Hexの引数(例:-Count)が 環境によって合わないことがある
もし
.ps1を作って実行するなら、VS Codeで 「UTF-8 with BOM」(または UTF-16 LE)で保存すると事故が減ります。
この記事はその前提で、Windows PowerShell 5.1でも確実に動く「.NET(ReadAllBytes)」を主役にして紹介します。
(PowerShell 7系の人向けに Format-Hex は補足として最後に載せます)
私の環境(参考)
-
Windows PowerShell 5.1.22621.6133
自分のバージョンを確認する方法
$PSVersionTable.PSVersion
結論(1行)
ファイル先頭に EF BB BF が見えたら「UTF-8 BOMあり」です。PowerShell 5.1なら .NET(ReadAllBytes) が最短・確実です。
まず前提:BOMって何を見ればいい?
UTF-8のBOM(Byte Order Mark)は、ファイル先頭の3バイトが固定です。
-
UTF-8 BOMあり →
EF BB BF -
BOMなし → 先頭に
EF BB BFが 出ない
※注意:BOMが無い=UTF-8確定ではありません(Shift-JISなどもあり得ます)。
この記事は「UTF-8 BOM(EF BB BF)があるか」を判定します。
重要:.\sample.csv は例です(ここで詰まりやすい)
この記事の .\sample.csv は 例のファイル名です。
あなたが確認したいファイルに置き換えてください。
-
カレントフォルダにあるなら:
.\yourfile.csv -
場所が違うならフルパスで:
D:\AI\blog\sample.csv
最短・確実(PS5.1対応):先頭3バイトを表示する(確認用)
※この方法は環境差に強く、Windows PowerShell 5.1でも安定して動きます。
# 例:確認したいファイルに置き換えてください
$path = ".\sample.csv"
# ファイルの存在チェック(コピペ事故防止)
if (-not (Test-Path -LiteralPath $path)) {
Write-Error "ファイルが見つかりません: $path"
return
}
# .NETでバイトとして読む(確実)
$all = [System.IO.File]::ReadAllBytes($path)
# 3バイト未満(空ファイルなど)は判定不能
if ($all.Length -lt 3) {
"ファイルが3バイト未満です(空ファイルなど)。BOM判定できません。"
return
}
# 先頭3バイトを16進で表示(EF BB BF が出たらBOMあり)
$head = $all[0..2]
'{0:X2} {1:X2} {2:X2}' -f $head[0], $head[1], $head[2]
見方(ここだけ)
-
EF BB BF→ UTF-8 BOMあり -
それ以外 → BOMなし(または別形式)
最短・確実(PS5.1対応):BOM判定まで一気に(True/False)
$path = ".\sample.csv"
if (-not (Test-Path -LiteralPath $path)) {
Write-Error "ファイルが見つかりません: $path"
return
}
$all = [System.IO.File]::ReadAllBytes($path)
$hasBom =
($all.Length -ge 3) -and
($all[0] -eq 0xEF) -and
($all[1] -eq 0xBB) -and
($all[2] -eq 0xBF)
$hasBom
-
True→ BOMあり(UTF-8 with BOM) -
False→ BOMなし(または別形式)
仕上げ:人間向けのメッセージで出す(コピペOK)
$path = ".\sample.csv"
if (-not (Test-Path -LiteralPath $path)) {
Write-Error "ファイルが見つかりません: $path"
return
}
$all = [System.IO.File]::ReadAllBytes($path)
$hasBom =
($all.Length -ge 3) -and
($all[0] -eq 0xEF) -and
($all[1] -eq 0xBB) -and
($all[2] -eq 0xBF)
if ($hasBom) {
'BOMあり(UTF-8 BOM: EF BB BF)'
} else {
'BOMなし(または別形式)'
}
複数ファイルをまとめてチェック(フォルダ運用向け・PS5.1対応)
※フォルダ内のCSV/JSON/TXTを「BOMあり/なし」で一覧表示します。
※空ファイルなど 短すぎるファイルは「判定不能」にします(落ちないようにする)。
$dir = "."
$patterns = @("*.csv","*.json","*.txt")
foreach ($pat in $patterns) {
Get-ChildItem -Path $dir -Filter $pat -File | ForEach-Object {
$path = $_.FullName
$all = [System.IO.File]::ReadAllBytes($path)
if ($all.Length -lt 3) {
'{0}`t{1}' -f '判定不能(短すぎ)', $path
} else {
$hasBom =
($all[0] -eq 0xEF) -and
($all[1] -eq 0xBB) -and
($all[2] -eq 0xBF)
'{0}`t{1}' -f ($(if ($hasBom) { 'BOMあり' } else { 'BOMなし' }), $path)
}
}
}
よくある質問:なぜ「文字」じゃなく「バイト」で見るの?
BOMは「文字」ではなく、ファイル先頭に付く バイト列の目印だからです。
-
文字として読むと、環境やデコードで挙動がブレる
-
バイトとして読むと、
EF BB BFをそのまま確認できる
BOM確認は バイトで見るのが正解です。
補足:Format-Hex を使う場合(PowerShell 7系向け)
Format-Hex は便利ですが、引数は環境差があります。
まず自分の環境で使える引数を確認してください。
Get-Help Format-Hex -Full
30秒まとめ
-
UTF-8 BOMありなら先頭3バイトが EF BB BF
-
BOMなし=UTF-8確定ではない(Shift-JIS等もあり得る)
-
PowerShellはバージョン差がある(5.1は引数で詰まりやすい)
-
PS5.1なら
.NET ReadAllBytesが最短・確実 -
フォルダ一括チェックで「混在」を早期発見できる
今日の1アクション
怪しいファイルを1つ選んで、まずはこれだけ:
$path=".\sample.csv"
$all=[System.IO.File]::ReadAllBytes($path)
($all.Length -ge 3) -and ($all[0] -eq 0xEF) -and ($all[1] -eq 0xBB) -and ($all[2] -eq 0xBF)
True なら BOMあり。
次はVS Codeで UTF-8(BOMなし) に保存し直すと再発が減ります。
今日のひとこと(いーかの成長ログ)
“見えない問題”は、バイトで見ると一発で見える。