|
|
> パイプ問題(?)への対応 |
H.Kamifuji . |
このページを 2016/06 に掲載してから、コマンドプロンプトの代用として利用してきました。現在(2020/11)においても、代用に成りきれない事項があります。しかも、改善されていない。 代用できない事項は、下記のコマンドが意図した動作をしないことだ! nkf -s xxx.txt > yyy.txt 上記のコマンドは、文字コードを Shift_JIS(cp932) に変換して、yyy.txt に格納するものです。コマンドプロンプトでは、正常に動作します。しかし、PowerShell では、UTF-16LE にて、格納されます。下記のコマンドで、 $OutputEncoding = [Console]::OutputEncoding 出力エンコードを、Shift_JIS に変更しても、何ら効果(変化)なしだ! PowerShell 奮闘記のページでも、help 情報を .txt ファイルにて、提供していますが、なんと、New Edge では、.mp3 と見なしているのか、音楽再生アプリが起動されるようだ! " > パイプ問題(?)" として、全ページ見直していきた。 そこで、Shift_JIS に変換、あるいは、パイプでファイルに保存するのに、多少なり便利になるツールを、作成したので、紹介します。 PowerShell 7.15 インストールに共ない見直します。 現在(2024/10/22)では、PowerShell 7.4.5 が最新のようです。見直しをはじめましたが、 何と、" > パイプ問題(?)"が 解 消 されています。 遡り確認したところ 7.3.9 は NG 7.4.0 で解消されていることが分かりました。 7.4.x をインストールしたなら、下記の検証は、不要です。cmd (コマンド・プロンプト) との行き来しながらの開発が解消されます。 |
$OutputEncoding で、出力文字コードを変更できそうです。 次のコードを実行すると、Shift_JIS 出力設定になるようです。 $OutputEncoding = [Console]::OutputEncoding $OutputEncoding上記を実行すると下記のような長文が表示されます。 PS >$OutputEncoding = [Console]::OutputEncoding PS >$OutputEncoding BodyName : iso-2022-jp EncodingName : 日本語 (シフト JIS) HeaderName : iso-2022-jp WebName : shift_jis WindowsCodePage : 932 IsBrowserDisplay : True IsBrowserSave : True IsMailNewsDisplay : True IsMailNewsSave : True IsSingleByte : False EncoderFallback : System.Text.InternalEncoderBestFitFallback DecoderFallback : System.Text.InternalDecoderBestFitFallback IsReadOnly : True CodePage : 932PowerShell 7.15 で、次のコードを実行すると、Shift_JIS 出力設定になるようです。 $OutputEncoding = [Console]::OutputEncoding $OutputEncoding上記を実行すると下記のような長文が表示されます。 PS >$OutputEncoding = [Console]::OutputEncoding PS >$OutputEncoding EncodingName : Japanese (Shift-JIS) WebName : shift_jis HeaderName : iso-2022-jp BodyName : iso-2022-jp Preamble : WindowsCodePage : IsBrowserDisplay : IsBrowserSave : IsMailNewsDisplay : IsMailNewsSave : IsSingleByte : False EncoderFallback : System.Text.InternalEncoderBestFitFallback DecoderFallback : System.Text.InternalDecoderBestFitFallback IsReadOnly : False CodePage : 932PowerShell 7.15 では、Shift_JIS マルチ文字が正常に表示されない。 PowerShell 5.1 とは、微妙に設定値がことなるようだ。WindowsCodePage 〜 IsMailNewsSave が設定値無しが日本語化(多国言語化)が実現できていない要因かな? ヘルプをファイルに保存するには、下記のようなリダイレクションを使用できそうです。 # 出力結果をファイルに保存する。 Get-Help Get-ChildItem -full > Get-ChildItem_help.txtしかし、Get-ChildItem_help.txt には、UTF-16LE で、保存されます。 下記のコードで、出力結果をクリップボードに保存できます。 # 出力結果をクリップボードに保存する。 Get-Help Get-ChildItem -full | clipクリップボードには、Shift_JIS で保存されています。 PowerShell では、> と | で、動作に差異があるようです。コマンドプロンプトや UNIX 系の shell では、同じ動作です。 UTF-xx と Shift_JIS の苦肉の共存を目指すようだが、駄作になっているようだ! 上記の Get-ChildItem_help.txt ファイルは、サーバー(Linux)環境で、nkf コマンドを利用して、各種コードに変換しました。 Get-ChildItem_help_w.txt ( UTF-8 ) Get-ChildItem_help_w8.txt ( UTF-8 BOM 付き ) Get-ChildItem_help_s.txt ( Shift_JIS ) です。 |
次のコードを実行すると、Shift_JIS 出力設定から、Default の us-ascii に戻します。$OutputEncoding = New-Object System.Text.ASCIIEncoding $OutputEncoding上記を実行すると下記のような長文が表示されます。 PS >$OutputEncoding = New-Object System.Text.ASCIIEncoding PS >$OutputEncoding IsSingleByte : True BodyName : us-ascii EncodingName : US-ASCII HeaderName : us-ascii WebName : us-ascii WindowsCodePage : 1252 IsBrowserDisplay : False IsBrowserSave : False IsMailNewsDisplay : True IsMailNewsSave : True EncoderFallback : System.Text.EncoderReplacementFallback DecoderFallback : System.Text.DecoderReplacementFallback IsReadOnly : True CodePage : 20127PowerShell 7.15 で、次のコードを実行すると、Shift_JIS 出力設定から、Default の utf-8 に戻します。 $OutputEncoding = New-Object System.Text.UTF8Encoding $OutputEncoding上記を実行すると下記のような長文が表示されます。 PS >$OutputEncoding = New-Object System.Text.UTF8Encoding PS >$OutputEncoding Preamble : BodyName : utf-8 EncodingName : Unicode (UTF-8) HeaderName : utf-8 WebName : utf-8 WindowsCodePage : 1200 IsBrowserDisplay : True IsBrowserSave : True IsMailNewsDisplay : True IsMailNewsSave : True IsSingleByte : False EncoderFallback : System.Text.EncoderReplacementFallback DecoderFallback : System.Text.DecoderReplacementFallback IsReadOnly : True CodePage : 65001PowerShell 7.15 でも、us-ascii と utf-8 の設定でも utf-xx Encoding なら正常に表示されます。 PowerShell 7.15 では、Shift_JIS マルチ文字が正常に表示されない。 PowerShell 5.1 では、Shift_JIS も、正常に表示されます。 以下、PowerShell 7.15 でも同様です。 ここでも、ヘルプをファイルに保存するには、下記のようなリダイレクションを使用できそうです。 # 出力結果をファイルに保存する。 Get-Help Get-ChildItem -full > Get-ChildItem_help_us.txt前項の Shift_JIS 設定と同様に、Get-ChildItem_help_us.txt には、UTF-16LE で、保存されます。 続いて、下記のコードで、出力結果をクリップボードに保存してみよう。 # 出力結果をクリップボードに保存する。 Get-Help Get-ChildItem -full | clipクリップボードには、UTF-16LE で保存されていると考えるが、下記のような ANSI のできそこないです。 ?? Get-ChildItem ?? Get-ChildItem [[-Path] <string[]>] [[-Filter] <string>] [<CommonParameters>] Get-ChildItem [[-Filter] <string>] [<CommonParameters>] ?????? -Attributes <FlagsExpression[FileAttributes]> ?? false ?? ???? ????????????? false ?????? ???? (???) ????? ?? ?? trueかな・漢字など複数バイト文字が ?? で、保存されているようです。 これは、全く使い物になりません! この設定でも、PowerShell では、> と | で、動作に差異があるようです。 |
下記のコードで、Shift_JIS で、保存できる フィルターコマンド( gtpipe ) を、作成します。# 出力結果をファイルに保存する。 $OutputEncoding = [Console]::OutputEncoding Get-Help Get-ChildItem -full | gtpipe Get-ChildItem_help.txt上記のコードを、Get-ChildItem_help.ps1 に保存して、下記にて実行します。
PS >./Get-ChildItem_help.ps1
出力結果は、Get-ChildItem_help.txt に Shift_JIS で保存されます。gtpipe コマンドは、下記の C 言語ソースで作成します。gtpipe.cpp に保存し、vs2019 なら、このページを、参考にして、cl gtpipe.cpp で、コンパイルできます。 // gtpipe.cpp : コンソール アプリケーション用のエントリ ポイントの定義 // #include <stdio.h> #include <string.h> int main(int argc, char* argv[]) { char buff[8192] ,fname[8192] ; int i ,oF ; FILE *bh ; if ( argc > 1 ) { strcpy( fname ,argv[1] ); } else { strcpy( fname ,"__w" ); } oF = fopen_s( &bh ,fname ,"w" ); if ( !oF ) { while ( !feof( stdin ) ) { i = fgetc( stdin ); fputc( i ,bh ); } fclose( bh ); } return 0; }作成した gtpipe.exe を、path の通ったディレクトリに保存してください。path の通ったディレクトリを持たない方は、「path の通し方:環境変数 path の設定方法」を見てください。 |
ここでは、前項の gtpipe コマンドと nkf コマンド (ネットワーク用漢字コード変換フィルタ) を、利用して、Shift_JIS ファイルに変換する PowerShell コマンドを作成してみました。 下記のコードを、nkf_ps.ps1 に作成してください。続いて、nkf_ps.ps1 を、パスの通ったディレクトリに保存してください。 $OutputEncoding = [Console]::OutputEncoding nkf -s $Args[0] | gtpipe $Args[1]下記ののように、実行します。
PS >nkf_ps 変換元ファイル 変換先ファイル
下記のように、実行すると Get-ChildItem_help.txt (漢字コード不問) を、Shift_JIS コードに変換して、Get-ChildItem_help_s.txt を、作成します。
PS >nkf_ps Get-ChildItem_help.txt Get-ChildItem_help_s.txt
下記のように、変換先ファイルを省略してときには、変換結果は、__w に保存されます。
PS >nkf_ps Get-ChildItem_help.txt
|
ここでは、変換元ファイルを、変換して、変換元のファイル名で、上書き保存する事例です。 下記のコードを、nkf_s.ps1 に作成してください。続いて、nkf_s.ps1 を、パスの通ったディレクトリに保存してください。 $OutputEncoding = [Console]::OutputEncoding nkf -s $Args[0] | gtpipe rm $Args[0] mv __w $Args[0]下記ののように、実行します。
PS >nkf_s 変換元ファイル
下記のように、実行すると Get-ChildItem_help.txt (漢字コード不問) を、Shift_JIS コードに変換して、Get-ChildItem_help.txt に、上書きします。
PS >nkf_s Get-ChildItem_help.txt
下記に、実戦でも有益な使用例を示します。$OutputEncoding が Default の us-ascii のまま、実行できますので、実務でも利用できると考えます。 PS >Get-Help Get-ChildItem -full > Get-ChildItem_help.txt PS >nkf_s Get-ChildItem_help.txt |
PowerShell 7.15 では、全ての Encoding で、Shift_JIS 出力において、文字化けが発生する。 PowerShell 5.1 では、全ての Encoding で、Shift_JIS 出力において、文字化け無く正常である。 結論(まとめ) 日本語環境で、Shift_JIS 出力アプリが存在する(将来的になくなるとは、思えない) Windows10 では、PowerShell 7.1X に移行できない。 |