1. ホーム
  2. powershell

[解決済み] PowerShellのデフォルトの出力エンコーディングをUTF-8に変更する

2022-05-28 01:12:10

質問

デフォルトでは、PowerShell でコマンドの出力をファイルにリダイレクトしたり、他の何かにパイプするとき、エンコーディングは UTF-16 で、これは便利ではありません。私はそれを UTF-8 に変更したいと考えています。

を置き換えることで、ケースバイケースで可能です。 >foo.txt 構文を | out-file foo.txt -encoding utf8 という構文がありますが、これは毎回繰り返さなければならないのが厄介です。

PowerShellで設定する永続的な方法は、設定内容を \Users\me\Documents\WindowsPowerShell\profile.ps1 ;このファイルが確かに起動時に実行されることを確認しました。

出力エンコーディングの設定は、これまで $PSDefaultParameterValues = @{'Out-File:Encoding' = 'utf8'} で設定できるとのことですが、試してみましたが効果はありませんでした。

https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/ について述べています。 $OutputEncoding は一見すると関連性があるように見えますが、出力が ASCII でエンコードされていることについて述べており、これは実際に起こっていることではありません。

PowerShell が UTF-8 を使用するように設定するにはどうすればよいですか?

どのように解決するのですか?

注意してください。

  • セクションは、主に Windows PowerShell .

  • いずれの場合も の情報は、PowerShell が読み取りと書き込みに UTF-8 を使用するようにするために適用されます。 ファイル .

    • これに対して を送受信する方法についての情報は、UTF-8 エンコードされた 文字列 との間で 外部プログラム を参照してください。 この回答 .

  • PSv5.1以降 で、ここで >>> は事実上 Out-File であれば のデフォルトエンコーディングを設定します。 > / >> / Out-File を経由して $PSDefaultParameterValues プリファレンス変数 :

    • $PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
      • Windows PowerShell (最新かつ最終版が v5.1 であるレガシー版) では、この は必ず UTF-8 ファイルを作成します。 を持つ (擬似) BOM .

        • 多くの Unix -ベースのユーティリティはこの BOM を認識しません (下を参照)。 このポスト を参照してください。
      • PowerShell (Core) v6+ , BOM-レス UTF-8 は デフォルト (次のセクション参照) ですが、もし する が必要な場合は 'utf8BOM'

  • PSv5.0またはそれ以下 では はできません。 のエンコーディングは変更できません。 > / >> が、しかし、上の PSv3 以上 では、上記の手法で への明示的な呼び出しに対して働きます。 Out-File .

    (その $PSDefaultParameterValues プリファレンス変数はPSv3.0から導入されました)。

  • PSv3.0以降 にしたい場合は のデフォルトエンコーディングを設定します。 全て をサポートするコマンドレットは

    an -Encoding パラメータ
    (これは PSv5.1+ では >>> ) を使用します。

    • $PSDefaultParameterValues['*:Encoding'] = 'utf8'

このコマンドを $PROFILE などのコマンドレットがあります。 として Out-FileSet-Content はデフォルトでUTF-8エンコーディングを使用しますが、これによって セッション・グローバル設定 で明示的にエンコーディングを指定しないすべてのコマンド/スクリプトに影響します。 -Encoding パラメータで明示的にエンコーディングを指定しないすべてのコマンド/スクリプトに影響します。

同様に にもそのようなコマンドが含まれるようにしてください。 スクリプト または モジュール と同じように動作させたい とすることで、別のユーザや別のマシンで実行した場合でも同じように動作します。 グローバル を変更する場合は、以下のフォームを使用して ローカル のコピー $PSDefaultParameterValues :

  • $PSDefaultParameterValues = @{ '*:Encoding' = 'utf8' }

については Windows PowerShell 標準コマンドレットの多くで、デフォルトの文字エンコーディングの動作に大きな矛盾があることを要約します。 については、一番下のセクションを参照してください。


自動的な $OutputEncoding 変数は 関係ない との通信方法にのみ適用され、PowerShell が 外部プログラム との通信方法 (PowerShell が外部プログラムに文字列を送信する際に使用するエンコーディング) にのみ適用され、出力リダイレクト演算子や PowerShell コマンドレットがファイルへの保存に使用するエンコーディングには関係ありません。


任意でお読みください。クロスプラットフォームの視点。PowerShell コア :

PowerShell は現在クロスプラットフォームです。 で、その PowerShell コア 版で、そのエンコーディングは - 感覚的に - をデフォルトとしています。 BOM-less UTF-8 で、Unix 系のプラットフォームと同じです。

  • これは、BOM のないソースコード・ファイルは UTF-8 と見なされることを意味します。 > / Out-File / Set-Content のデフォルトは BOM-レス UTF-8。 utf8 -Encoding 引数もまた BOM-less UTF-8 を作成しますが、ファイル での擬似BOMは utf8bom の値で指定します。

  • PowerShell スクリプトを Unix 系のプラットフォームでエディターを使って作成する場合、最近では Windows であっても、Visual Studio Code や Sublime Text のようなクロスプラットフォーム エディターで PowerShell スクリプトを作成した場合、作成された *.ps1 ファイルは通常 ではなく はUTF-8擬似BOMを持っています。

    • これは PowerShell 上で問題なく動作します。 コア .
    • で壊れる可能性があります。 Windows PowerShell スクリプトで非 ASCII 文字を使用する必要がある場合、UTF-8 で保存してください。 で保存し、BOM .

      BOM がない場合、Windows PowerShell はスクリプトが従来の "ANSI" コードページ (Unicode 以前のアプリケーションのシステム ロケールによって決定される; 例えば、US-English システムの Windows-1252) でエンコードされていると (誤った) 解釈をします。
  • 逆に する が UTF-8 疑似 BOM を持っているファイルは、 Unix 系プラットフォームでは問題があります。 cat , sed そして awk - のようなエディタもありますし gedit - から を通して擬似BOMを渡します。 として扱うこと、すなわち データ .

    • これは 常に でファイルを文字列に読み込もうとしたときなど、間違いなく問題になりえます。 bash で、例えば text=$(cat file) または text=$(<file) - の場合、結果として得られる変数には最初の3バイトとして擬似BOMが含まれます。

での一貫性のないデフォルトのエンコーディングの動作 Windows PowerShell :

残念なことに、Windows PowerShell で使用されるデフォルトの文字エンコーディングは一貫性がなく、クロスプラットフォームな PowerShell コア

版では、前のセクションで説明したように、称賛に値することに、これに終止符を打ちました。

注意してください。

  • 以下はカバーすることを目的とはしていません。 すべて 標準的なコマンドレットを網羅することを意図しています。

  • コマンドレット名をググってそのヘルプトピックを探すと、現在では PowerShell の コア バージョンに切り替えるには、左側のトピック一覧の上にあるバージョン ドロップダウン リストを使用します。 Windows PowerShell バージョンに切り替えることができます。

  • この記事を書いている時点では、Windows PowerShell のデフォルトのエンコーディングは ASCII であると、しばしばドキュメントで誤って主張されています。 GitHub docs のこの問題 .


以下のようなコマンドレットがあります。 を書く :

Out-File そして > / >> ユニコードの作成 UTF-16LE - このファイルでは、すべての ASCII 範囲の文字 (も) は、次のように表現されます。 2 バイト - これは、特に Set-Content / Add-Content (次のポイント参照)。 New-ModuleManifestExport-CliXml もUTF-16LEファイルを作成します。

Set-Content (そして Add-Content は ANSI エンコーディング (アクティブなシステムロケールの ANSI レガシーコードページで指定されたエンコーディングで、PowerShell では Default ).

Export-Csv は確かにドキュメント通りに ASCII ファイルを作成しますが、 注意書きを参照してください。 -Append を参照してください。

Export-PSSession は、デフォルトでBOM付きのUTF-8ファイルを作成します。

New-Item -Type File -Value は現在、BOMなし(!)のUTF-8を作成します。

Send-MailMessage ヘルプのトピックでは、ASCII エンコーディングがデフォルトであるとも主張しています - 私は個人的にその主張を検証していません。

Start-Transcript 必ず はUTF-8ファイルを作成します。 のBOMを作成しますが、注意事項を参照してください。 -Append を参照してください。

Re コマンドは を追加する を既存のファイルに追加するコマンドを紹介します。

>> / Out-File -Append 作る いいえ は、ファイルのエンコーディングの一致を試みます。 既存のコンテンツ . つまり、デフォルトのエンコーディングを盲目的に適用します。 -Encoding で指示されない限り、デフォルトのエンコーディングを適用します。 >> を使うことはできません (ただし、PSv5.1+では $PSDefaultParameterValues を介した間接的なものを除く)。 要するに、既存のファイルのコンテンツのエンコーディングを知り、その同じエンコーディングを使用して追加する必要があります。

Add-Content は賞賛に値する例外です。 -Encoding 引数がない場合、既存のエンコーディングを検出し、それを自動的に新しいコンテンツに適用します。 ありがとうございます。 js2010 . なお、Windows PowerShellでは、既存のコンテンツにBOMがない場合に適用されるのはANSIエンコーディングですが、PowerShell CoreではUTF-8になることに注意してください。

の間のこの不整合は Out-File -Append / >> そして Add-Content で、これはPowerShellにも影響します。 コア で説明されています。 このGitHubの課題 .

Export-Csv -Append 部分的に は既存のエンコーディングと一致します。 UTF-8 を追加しますが、UTF-16LE と UTF-16BE には正しくマッチします。

別の言い方をすれば、BOM がない場合。 Export-Csv -Append は UTF-8 を想定しているのに対し Add-Content はANSIを想定しています。

Start-Transcript -Append 部分的に は既存のエンコーディングにマッチします。これはエンコーディングに正しくマッチします とBOM にマッチしますが、それがない場合は、潜在的に損失の大きい ASCII エンコーディングにデフォルトでマッチします。


以下のようなコマンドレットがあります。 読む (で使用されるエンコーディング(つまり BOM がない場合 ):

Get-Content そして Import-PowerShellDataFile は、デフォルトでANSI ( Default ) と一致します。 Set-Content .

ANSI は、PowerShell エンジン自身がデフォルトで読み込むものでもあります。 ソースコード をファイルから読み込むときのデフォルトでもあります。

これに対して Import-Csv , Import-CliXmlSelect-String はBOMがない場合、UTF-8と仮定します。