PowerShellの日本語文字コード
PowerShellで日本語テキストファイルを処理するときの原則をまとめた。
- 入力テキストファイルはシフトJISかUTF-16とする。
- PowerShellスクリプトファイルはシフトJISかUTF-16で保存する。
- ファイルに結果を出力するときは、簡易的には「>」でよいが、スクリプトにするときはOut-Fileコマンドレットに-Encodingオプションを付けて文字コードを明示する。
- 入力ファイルのエンコーディングも、指定できるコマンドレットでは明示しておく。
- 文字コードを自動判定し、現在の文字コードを表示できるエディタを使う(例えば秀丸エディタ)。
きっかけは、Deliciousからエクスポートしたブックマークと、Googleブックマークにインポートしたものが一致するかどうかを、PowerShellで検証してみようと思ったことである。双方からエクスポートしたファイル(UTF-8)をソートして件数を比較しようとしたら、文字化けしたりして一筋縄ではいかなかった。
まずPowerShellの文字コードはUnicode(UTF-16)が基本である。Windowsの内部表現がUTF-16なのでもっともだ。たとえばファイル一覧を出力するGet-ChildItemコマンドレット(エイリアスls)の結果をファイルに出力してみる。
ls > file_list.txt
このときfile_list.txtの中身はUTF-16である。シフトJISやUTF-8で出力したいときは、Out-Fileコマンドレットを使ってエンコーディングを指定すればよい。日本語Windowsでdefaultを指定するとシフトJISになる。
ls | Out-File file_list.txt -Encoding default
ls | Out-File file_list.txt -Encoding UTF8
Select-Stringコマンドレット(エイリアスgrep)は、入力ファイルのエンコーディングを指定できる。デフォルトはUTF-16を意味する「Unicode」であるが、このままでUTF-8のファイルも正しく処理できてしまうのは、便利とも紛らわしいとも言える。
Select-String input.txt -pattern "検索文字列"
入力ファイルがシフトJISのときはdefaultを指定する。この場合はもちろんUTF-8やUTF-16のファイルを処理できない・・・と思ったら、UTF-16は処理できてしまった。UTF-8は処理できない。頭がこんがらがる。
Select-String input.txt -pattern "検索文字列" -Encoding default
スクリプトで実行する場合は、スクリプトファイルをUnicode(UTF-16)かシフトJISで保存しておく。UTF-8でスクリプトファイルを書くと、日本語文字列の部分を正しく認識できずエラーになる。
Get-Contentコマンドレット(エイリアスcat)でファイルの中身を出力したり他のコマンドレットにパイプで渡したりするときは、入力ファイルをUTF-16かシフトJISにしておく。UTF-8だと盛大に文字化けしてしまう。
cat input.txt > output.txt
cat input.txt | sort > output.txt
input.txtがUTF-8だとoutput.txtの中身は文字化けする。シフトJISのinput.txtの場合は、Unicodeにコード変換したoutput.txtが生成される。細かくチェックしてないが、正しく変換しているようだ。UNIXならファイルコピーと同義の「cat input.txt > output.txt」がコード変換してしまうので、UNIX屋は頭がこんがらがる。
入力ファイルや出力ファイルにどんな文字コードを想定しているかをスクリプトに明示しておけば、あとで読んだり、他の人が読んだりしたときに混乱しないだろう。
コンソールに出力するWrite-Outputはエンコーディングが指定できないから、出力をファイルにリダイレクトすると、UTF-16のファイルができてしまう。これを別の文字コードに変換するにはnkf等を使えばよい。たとえばCygwinでテキスト処理するときはUTF-8に変換すればよい。
nkf.exe -W16 -w8 -O <入力ファイル> <出力ファイル>
(参考記事)
GUIユーザーのためのPowerShell入門(第11回)の囲み部分「日本語文字コードに注意」
http://journal.mycom.co.jp/column/powershell/011/index.html
| 固定リンク
この記事へのコメントは終了しました。
コメント