Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

各種処理の入出力文字コード設定方法

PowerShellにおける文字コード周りの扱いがカオスすぎたので表にまとめたが、依然としてカオスすぎる。対応しそうな処理の方針がまるでバラバラになっている。

# 処理 デフォルト 変更方法 自動判定可能な文字コード
1 Get-Content(ファイルの読み込み) シフトJIS (MS932)*1 -Encodingオプションで指定(PowerShell 2.0でも使用可*2 UTF-16LE(BOMあり)、UTF-16BE(BOMあり)、UTF-8(BOMあり)
2 Set-Content(ファイルへの書き出し) シフトJIS (MS932)*3 -Encodingオプションで指定(PowerShell 2.0でも使用可*4 -
3 Import-CsvCSVファイルの読み込み) ASCII -Encodingオプションで指定(PowerShell 2.0では使用不可) UTF-16LE(BOMあり)、UTF-16BE(BOMあり)、UTF-8(BOMあり、BOMなし)
4 Export-CsvCSVファイルへの書き出し) ASCII -Encodingオプションで指定(PowerShell 2.0でも使用可) -
5 外部コマンドの標準出力の読み込み シフトJIS (MS932)*5 [Console]::OutputEncodingを変更するか、System.Diagnostics.Processを使ってコマンドを実行するよう処理を変更*6する*7 未調査
6 リダイレクトによるファイルへの書き出し UTF-16LE(BOMあり) ない。[Console]::InputEncodingおよび[Console]::OutputEncodingの影響は受けない。Out-Fileへ渡した上で-Encodingを指定するよう処理の変更が必要 -
7 Out-File(ファイルへの書き出し) UTF-16LE(BOMあり) -Encodingオプションで指定(PowerShell 2.0でも使用可) -
8 Windows PowerShell ISEでファイルを開く - なし シフトJIS (MS932)、TF-16LE(BOMあり)、UTF-16BE(BOMあり)、UTF-8(BOMあり)
9 Windows PowerShell ISEでファイル保存 UTF-16BE(BOMあり) なし -
  • ○○-Contentと○○-Csvとリダイレクト系の処理でデフォルトの文字コードが全部違う
  • Export-CsvにはEncodingオプションがあるのにImport-CsvにはないPowerShell 2.0
  • Get-Contentで-Encodingが指定できないと、PowerShell 2.0では日本語の入ったCSVの読み込みがだいぶキツいのだが、そんな中Get-Helpに書かれていない-Encodingオプション
  • なぜかImport-CsvだけはBOMなしCSVの自動判定に対応している
  • パイプで他のコマンドの出力読むときは[Console]の設定を読むけどリダイレクトでファイルに吐くときは読まない
  • パイプで他のコマンドの出力読むときはSJIS前提なのに、リダイレクトでファイルに吐くときはUTF-16LE
  • PowerShell ISEで保存したファイルの文字コードがなぜかUTF-16BE

といったところが味わい深い。特に「PowerShell ISEで保存するとUTF-16BEになる」ってのは狙ってるんじゃないかと思えるくらいヒドい。x86でビッグエンディアンって何かメリットあるのか?


その他の小ネタとしては……

  • ConvertFrom-Csv(文字列をCSVとしてパース)およびConvertTo-Csv(オブジェクトをCSV形式の文字列に変換)への入出力はPowerShellの内部処理を必ず経由する(常にUTF-16LEとなる)ため、文字コードの指定方法はない。
  • [Console]::InputEncodingおよび[Console]::OutputEncodingのデフォルト値は[System.Text.Encoding]::Default。
  • [System.Text.Encoding]には文字コードとしてASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, UTF8が定義されているが、[Console]::InputEncodingおよび[Console]::OutputEncodingに設定できるのはこのうちASCII, Default, UTF7, UTF8のみ。

*1:厳密には[System.Text.Encoding]::Defaultに従う。[Console]::InputEncodingの影響は受けない

*2:PowerShell 2.0ではGet-Helpの内容に-Encodingオプションについて記述がないが、実際には使用可能

*3:厳密には[System.Text.Encoding]::Defaultに従う。[Console]::OutputEncodingの影響は受けない

*4:PowerShell 2.0ではGet-Helpの内容に-Encodingオプションについて記述がないが、実際には使用可能

*5:厳密には[Console]::OutputEncodingに従う

*6:http://aquasoftware.net/blog/?p=378

*7:[Console]::OutputEncodingを[System.Text.Encoding]::Default以外に変更すると、コンソールのフォントが強制的にLucida Consoleに変更されてしまい日本語が表示できなくなってしまうので注意。[System.Text.Encoding]::Defaultに設定すると元に戻る