BOMなんとかしたい
本日の一曲。
「csv 文字化け」とかで検索すると色々と出てくるアレです。
下の動画、Tips的な展開を見せると思いきや、結局「間違って消したり上書きしちゃった時にはうちの製品使いなよ」的に強引に持っていく、ある意味潔い感じに話を組み立ててますね。ちゃんと「別の場所に保存ね」って言っているからまあevilではないかな。
CSV?
"The Comma Separated Value (CSV) File"のことです。","で区切られたテキスト列のファイルですね。
CSVファイルについての解説、RFC4180見ていくとStatusが "Informational" ってなってますね。これ、RFC8259で "Internet Standard" になっているJSONとは違って、「『標準規格』にまで至っていない」ということですね。ですので、ほかの人から『CSVファイルの規格通りに』とかそういう風な話が出た場合にはもう少し細かく聞いてみた方が良い場面もあります。
このCSVファイル文字化けするんですけどぉ〜?
さて、ExcelでCSVファイルを読み込んだ時に何故か漢字や仮名を使っている部分が文字化けする、というケースがあると思います。
OSはWindows
CSVファイルを直接ダブルクリックで開いている(関連づけられたExcelが起動する設定)
他から送られてきたCSVファイル(orプログラム等で自動的に生成されたもの)
仮名と漢字、全角文字部分が文字化けしているっぽい
試しに直接テキストエディタで開いてみたけど文字化けは起こさなかった
上記のようなパターンで、「あれれ、おかしーなー?」ってなった時に、上記の動画のような方法を試す感じになるんでしょうね、っていうのは想像できます。
テキストエディタだと正しく見えるけど?
それは「テキストエディタ側がよしなにやってくれるから」。
とりあえず16進ダンプでも出してみましょうか…以下では「あ」一文字をそれぞれ以下のファイル名で保存しているとして話を進めます。
sample.txt - UTF8
sample_bom.txt - UTF8(BOM付き)
sample_sjis.txt - Shift-JIS
では今回はPowershellのhexdumpコマンドを使った出力で中身を見てみましょう。
PS /private/tmp> Get-ChildItem *.txt | select name
Name
----
sample_bom.txt
sample_sjis.txt
sample.txt
PS /private/tmp> hexdump sample.txt
0000000 e3 81 82
0000003
PS /private/tmp> hexdump sample_bom.txt
0000000 ef bb bf e3 81 82
0000006
PS /private/tmp> hexdump sample_sjis.txt
0000000 82 a0
0000002
PS /private/tmp>
Windows メモ帳で開いてみて「右下」を確認
最近のWindows メモ帳だと、開いたファイルの文字コードおよびBOM有り無しをステータスバーに表示してくれます。
実は「ファイル読み込み時にテキストのエンコーディングを自動的に判定する」ことをやっていることがあります。なので先ほど挙げた3種類とか気にする必要がこれまでなかった、ということかもしれません。
ひとまずほかのエディタでも、テキストのエンコーディングを判別して編集できるようにしていること、また多くはステータスバー等で使用エンコーディングやBOM有り無しの情報を表示してくれます。試してみたらいいさ。
ExcelでBOMなしUTF8のファイルを開いてみた
お約束的な流れではありますが、sample.txt(UTF-8,BOMなし)を sample.csvというファイル名に変更して、Excel で開いてみると…
わーいやったー、文字化けしてるー。
sample.csv- UTF8 ※文字化け発生
sample_bom.csv - UTF8(BOM付き)
sample_sjis.csv - Shift-JIS -
じゃあBOMつけてあげれば良いので、こうかな?
[byte[]]$b=@(0xef,0xbb,0xbf)
[byte[]]$c=[System.IO.File]::ReadAllBytes('./sample.txt')
$o=$b+$c
[System.IO.File]::WriteAllBytes('./sample_bom.csv',$o)
16進ダンプで確認。
PS /private/tmp> hexdump sample_bom.csv
0000000 ef bb bf e3 81 82
0000006
PS /private/tmp> cat sample_bom.csv
あ
これでExcelで開いても安心ですね(?)