Macで文字コードをUTF-8に変換する|崩れた文字を戻す
mac utf 8 変換で検索したとき、本当に必要なのはコマンドの1行ではありません。手元のファイルがいま何のコードで書かれているのかが分からないまま変換をかけて、文字が消えたり増えたりするのが一番困る場面です。この記事では、見分ける、変換する、結果を確かめる、という3つの段に分けて、Macに最初から入っている道具だけでどこまで済むのかを並べます。
Shift_JISのファイルは、いまも届き続けている
社内の帳票、取引先から送られてくるCSV、古い基幹システムから吐き出される明細。この種類のファイルは、いまでもShift_JISやCP932で作られています。Windows版のExcelが長くその形で書き出してきたことと、受け取る側のシステムが変更されないまま残っていることが理由です。
送る側にとっては何も問題が起きていないので、変換の負担は受け取ったMacの側に一方的に乗ります。そのため「相手に直してもらう」という筋は現実には通らず、手元で変換する手順を1つ持っておくほうが早く終わります。
変換そのものは一瞬です。時間を取られるのは、その前後にある3つの判断です。1つ目は、いま何のコードなのかを見分けること。2つ目は、変換先をUTF-8のどの形にするのか、つまりBOMを付けるのか付けないのかを決めること。3つ目は、変換の途中で落ちた文字が無いかを確かめることです。この3つを飛ばして変換だけ実行すると、うまくいったように見えて数字や記号が1文字だけ消えている、という後から気づく壊れ方をします。
この記事で扱う道具は3つです。Macに最初から入っている iconv と textutil、そして後から入れる nkf。それぞれ得意な場面が違うので、どれが1つあれば足りるという話にはなりません。
いまの文字コードを見分ける方法と、その限界
最初に打つのは file です。Macには /usr/bin/file が入っており、I のオプションを付けると文字コードを推測して返します。
file -I 明細.csv
ここで覚えておく点が1つあります。UTF-8のファイルなら charset=utf-8 と素直に返りますが、Shift_JISのファイルに対しては charset=unknown-8bit と返ります。Macに入っている file はバージョン 5.41 で、日本語の1バイト超のコードを名前で言い当てるところまでは踏み込みません。つまり「utf-8 と出なければ、UTF-8ではない」という判断に使う道具であって、「何のコードか」を教えてくれる道具ではありません。
もう1つの見分け方が textutil です。Apple純正のコマンドで、info を付けるとファイルの種類、バイト数、文字数、先頭の内容を表示します。文字数が表示されるということは、読めているということなので、先頭の数文字が正しく出ていれば中身の見当は付きます。
file -Iで utf-8 と出る: 変換は不要file -Iで unknown-8bit と出る: Shift_JISかCP932かEUC-JPのどれかtextutil -infoで先頭が化けて出る: 指定したコードの読み方が違っている
実務では、送り主とファイルの出どころで当たりが付きます。Windows版のExcelから書き出したCSVならCP932、古いUNIX系のシステムから来たテキストならEUC-JP、というあたりから当てていくと、試す回数は2回で済みます。
iconv で変換する
Macには /usr/bin/iconv が入っています。追加でインストールするものはありません。基本の形は、元のコードと変換先のコードを指定して、結果を別のファイルに書き出す1行です。
iconv -f CP932 -t UTF-8 明細.csv > 明細_utf8.csv
ここで大事なのは、元のコードに SHIFT_JIS ではなく CP932 を指定することです。この2つは同じもののように扱われがちですが、iconvの中では別のコードとして登録されています。手元のMacで確かめると、丸囲みの1や株式会社の記号を含むテキストを SHIFT_JIS 指定で変換しようとした場合は iconv(): Illegal byte sequence で止まり、CP932 指定なら通ります。Windows側で追加された文字が含まれているかどうかが分かれ目で、日本の事務で使うファイルはCP932だと考えたほうが空振りが減ります。
止まったときに -c を足すと通るようになりますが、これは変換できない文字を黙って捨てる指示です。手元での確認では、丸囲みの1を含む行に -c を付けて変換したところ、その文字だけが消えて残りは正常に出ました。警告は1行出ますが、出力されたファイルを見ただけでは欠けに気づけません。金額や品番が入ったファイルで使う選択ではありません。
変換先の書き方も2つあります。UTF-8 と指定するとBOMは付きません。UTF-8-MAC という指定もありますが、これは後の節で触れる濁点の扱いが変わるもので、通常の変換で選ぶものではありません。
textutil で変換する
textutil はテキストの形式変換を担当するApple純正のコマンドで、文字コードの指定にも対応しています。読み込むときのコードと書き出すときのコードを別々に指定します。
textutil -convert txt -inputencoding CP932 -encoding UTF-8 -output 明細_utf8.csv 明細.csv
iconvとの違いは2つあります。1つは、出力先をオプションで渡すので、リダイレクトの記号を打ち間違えて元のファイルを空にする事故が起きにくいこと。もう1つは、読み込むときのコードを省略するとBOMから自動で判定しようとするので、BOM付きのファイルなら指定なしで通ることです。
出力にBOMが付くかどうかは確かめておく価値があります。手元で -encoding UTF-8 を指定して書き出したファイルの先頭を見ると、BOMの3バイトは入らず、いきなり本文のバイトから始まります。つまりBOMが要る場面では、この方法だけでは足りません。
- 出力先を間違えたくない: textutil
- 変換できない文字を確実に検出したい: iconv
- BOMを付けたい: どちらでも付かないので、後から足す
nkf を入れる場合の利点と手間
nkf は日本語の文字コード変換に的を絞った道具で、自動判別が強いのが特徴です。Macには最初から入っていないので、Homebrewで追加します。Homebrewの公式の一覧では、安定版として 2.1.5 が登録されています。
自動判別は g のオプションで確かめられます。ここが file -I との一番の違いで、Shift_JISやEUC-JPを名前で返します。変換のオプションも覚えやすい形に整理されています。
w : UTF8コードを出力(BOM無し) e : EUCコードを出力 s : Shift-JISコードを出力 g(guess) : 文字コード自動判別の結果を表示 overwrite : 元のファイルを上書きする 出典: miginihitsuji.com
自動判別と上書きが揃っているので、届いたファイルの束を1つのコマンドで片付けられます。これがnkfを入れる最大の利点です。
手間の側も見ておきます。Homebrewを入れていないMacでは、その導入から始まります。自動判別は推測なので、短いファイルや数字だけのファイルでは外れます。上書きのオプションは元のファイルを残さないので、控えを取らずに実行した場合の取り返しがつきません。届くファイルが月に数本なら、標準で入っている2つで足ります。毎日まとまった本数が届くなら、入れたほうが手が速くなります。
Excelで開くと崩れる場合の対処
UTF-8に変換したのに、Windows版のExcelでダブルクリックして開くと崩れる。この症状は変換の失敗ではなく、Excelの側が拡張子だけを見てCP932として読もうとしているために起きます。
避け方は2つです。1つはファイルの先頭にBOMの3バイトを足すこと。BOMが付いていれば、ExcelはUTF-8として読みます。iconvにもtextutilにもBOMを付けるオプションが無いので、先頭に足してから中身を繋げます。
{ printf '\xef\xbb\xbf'; cat 明細_utf8.csv; } > 明細_excel.csv
もう1つはUTF-16に変換する方法です。iconv -f UTF-8 -t UTF-16LE で書き出すと、これもExcelが正しく読みます。ただし文字あたりのバイト数が増えるので、行数の多いファイルでは容量が膨らみます。
付けたBOMが後で邪魔になる場面もあります。プログラムがCSVを1行目から読むとき、BOMの3バイトが1列目の見出しの前に残るので、見出しの名前が一致しなくなります。渡す相手が人なのかプログラムなのかで、付けるかどうかが変わります。同じ台帳を人にもプログラムにも渡す場合は、BOM無しを本体として置いておき、Excelに渡す用のものをその場で作るほうが管理が楽です。
Macだけで起きる、濁点が分かれる崩れ方
もう1つ、Macに固有の崩れ方があります。文字は正しく読めているのに、「が」や「ぱ」の濁点と半濁点だけが後ろにずれて見える、あるいは検索でその文字が引っかからない。これは文字コードの取り違えではなく、同じUTF-8の中で表し方が2通りあることから起きます。
手元のMacで確かめると、「が」を通常のUTF-8で書いた場合は3バイトの1文字です。同じ文字を UTF-8-MAC として書き出すと、「か」の3バイトと濁点の3バイトに分かれた6バイトになります。見た目は同じで、バイト列が違います。
- ファイル名がおかしい: Macのファイルシステムがこの分かれた形を使う場面がある
- 検索で引っかからない: 検索する文字列と本文の形が違っている
- 重複しているように見える: 2つの形が混ざったまま並んでいる
戻し方は、iconv -f UTF-8-MAC -t UTF-8 を通すことです。逆向きに変換すると、分かれていた濁点が1文字にまとまります。Windowsから届いたファイルを変換するときには関係しませんが、Macで長く扱ってきたファイルや、外付けディスクを経由したファイルでは起きます。文字コードの指定を何度変えても直らないときは、ここを疑うと早く終わります。
フォルダ単位でまとめて変換するときの順番
1本なら手で打てますが、届いたフォルダの中に数十本ある場合は手順を決めておく必要があります。順番は、控えを取る、1本で試す、残りに当てる、結果を数える、の4段です。
mkdir -p 変換前 && cp *.csv 変換前/
for f in *.csv; do iconv -f CP932 -t UTF-8 "$f" > "utf8_$f" || echo "失敗: $f"; done
上の書き方にしておくと、変換に失敗したファイルの名前がその場で出ます。まとめて実行したときに一番困るのは、全部終わったように見えて数本だけ壊れている状態なので、失敗した名前が残る形にしておくと後の追いかけが要りません。
終わったら本数を数えます。元のファイルの数と出力の数が合っているか、出力のバイト数が0のものが無いか。この2つだけ見れば、途中で落ちたものは見つかります。
変換の作業そのものより、行き来で時間が減る
ここまでの手順は、どれも1行か2行で終わります。それでも半日かかることがあるのは、コマンドが難しいからではありません。届いたファイルをFinderで探し、ターミナルに切り替えてパスを打ち、変換して、またFinderに戻って中身を確かめる。この行き来が1本あたり4回発生し、本数の分だけ積み上がるからです。
フォルダとターミナルとAIが同じ窓にある作りを選ぶと、フォルダを開いた時点でその場所のターミナルが立っているので、パスを打ち直す手間と、窓を切り替える手間が消えます。文字コードの変換は、まさにその行き来が効く種類の作業です。
ファイル管理の側にどういう機能が入っているかはできることにまとめてあります。変換を仕掛けたまま席を離れることが多いなら、iPhone・iPadから続きをで、出先の端末から自分のMacのターミナルとフォルダをどう扱えるかを説明しています。日本語以外のファイルを扱う場合の画面の言語については対応言語に一覧があります。
他のファイル管理との違いを先に見ておきたい場合は他のファイル管理との比較が近道です。費用の区切り方は料金に書かれており、残った疑問はよくある質問の側で答えが付いています。
決める順番をもう一度並べると、file -I で UTF-8 かどうかを見る、CP932を第一候補として iconv を1本で試す、落ちた文字が無いかを確かめる、渡す相手に合わせてBOMを付けるか決める。この4段で、届いたファイルの大半は片付きます。
よくある質問
元の文字コードが分からないときは、何から試せばよいですか?
file -I で UTF-8 かどうかを先に切り分けます。unknown-8bit と返ったら、Windows由来のファイルならCP932、UNIX系のシステム由来ならEUC-JPの順で試します。2回で当たらないことはほとんどありません。名前で判定したい場合は、Homebrewでnkfを入れて自動判別のオプションを使います。
iconv で Illegal byte sequence と出て止まります。どうすればよいですか?
元のコードの指定を SHIFT_JIS から CP932 に変えると通ることが多いです。丸囲みの数字や株式会社の記号のように、Windows側で追加された文字が含まれていると、SHIFT_JIS指定では扱えません。-c を付けると通りますが、変換できない文字が黙って消えるため、金額や品番が入ったファイルには向きません。
UTF-8に変換したのにExcelで崩れます。原因はどこですか?
変換は成功していて、Excelの側がCP932として読もうとしています。ファイルの先頭にBOMの3バイトを足すか、UTF-16LEに変換すると正しく開きます。ただしBOMを足すと、プログラムがCSVを読むときに1列目の見出しが一致しなくなるため、渡す相手で使い分けます。
濁点だけがずれて見えるのは文字コードの問題ですか?
文字コードの取り違えではなく、同じUTF-8の中で表し方が2通りあることから起きています。「が」が1文字ではなく「か」と濁点の2つに分かれた形で保存されている状態です。iconv -f UTF-8-MAC -t UTF-8 を通すと1文字にまとまります。Macで長く扱ってきたファイルで起きやすい崩れ方です。