目新しい情報ではないですが、ハマったのでメモ。
問題
次のPowershellスクリプト、それぞれどのようなエンコーディングでファイル出力されるでしょうか。
"あいうえお" | out-file "unspecified.txt"
"あいうえお" | out-file "default.txt" -Encoding default
"あいうえお" | out-file "unicode.txt" -Encoding unicode
"あいうえお" | out-file "utf8.txt" -Encoding UTF8
"あいうえお" | out-file "utf8bom.txt" -Encoding utf8BOM
"あいうえお" | out-file "utf8nobom.txt" -Encoding utf8NoBOM
$shiftjis = [Text.Encoding]::GetEncoding("Shift-JIS")
"あいうえお" | out-file "shiftjis.txt" -Encoding $shiftjis
解答
powershellのエンコーディング周りはv6で破壊的変更があり、WindowsにプリインストールのPowershell(v5)と最新のPowershell(v6+)で動作が違います。
| Encodingの指定 | Windows Powershell | Powershell |
|---|---|---|
| なし | UTF-16LE | UTF-8 |
| Default | ANSI(Shift-JIS) | UTF-8 |
| unicode | UTF-16LE | UTF-16LE |
| UTF8 | UTF-8-BOM | UTF-8 |
| utf8BOM | エラー(非対応) | UTF-8-BOM |
| utf8NoBom | エラー(非対応) | UTF-8 |
| shift-jis | エラー(非対応) | Shift-JIS |
出力別逆引き
| 出力したいEncoding | Windows Powershell | Powershell |
|---|---|---|
| UTF-8 | 不可能(※) | UTF8 |
| UTF-8-bom | UTF8 | utf8BOM |
| shift-jis | default | [Text.Encoding]::GetEncoding("Shift-JIS") |
| UTF-16LE | unicode | unicode |
(※)Encodingの指定だけでは不可能だが、工夫次第で可能(参考リンク)
なお、v6以降であれば、shift-jisに限らず[Text.Encoding]が扱えるエンコーディングはすべて扱えます。
まとめ
未指定とdefaultで挙動が違ったり、UTF-16LEの指定がunicodeだったりと、クセが多いです。ちなみに使うことはないと思いますが、UTF-16BEはBigEndianUnicodeです…。
Powershellは最近のWindowsなら標準で使えるので、ちょっとしたスクリプトを書くのにも便利ですが、手元のPowershellで動作確認したのに、他の環境に持っていったら動かない、みたいなバグを踏みがちです。chatGPTに書いてもらったコードをそのまま使う場合などは特に気をつけましょう……(一敗)
にしても、どの文字コードで出力するにしても、両方で動く書き方がないんだけど。どうなってんだ。UTF16で扱えってか。