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-Csv(CSVファイルの読み込み) | ASCII | -Encodingオプションで指定(PowerShell 2.0では使用不可) | UTF-16LE(BOMあり)、UTF-16BE(BOMあり)、UTF-8(BOMあり、BOMなし) |
4 | Export-Csv(CSVファイルへの書き出し) | 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に設定すると元に戻る