![GnuWin32 / sed の Powershell での予期しない動作](https://rvso.com/image/1428756/GnuWin32%20%2F%20sed%20%E3%81%AE%20Powershell%20%E3%81%A7%E3%81%AE%E4%BA%88%E6%9C%9F%E3%81%97%E3%81%AA%E3%81%84%E5%8B%95%E4%BD%9C.png)
使っていますGNUWin32 のWindowsコマンドラインツール/パワーシェル。
何が見えるか:
11:15 enlil D:\Users\x> Get-ChildItem .gitconfig | sed "s/ */ /g"
D i r e c t o r y : D : \ U s e r s \ x
M o d e L a s t W r i t e T i m e L e n g t h N a m e
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- a - - - 6 / 2 3 / 2 0 1 4 4 : 1 1 P M 5 6 . g i t c o n f i g
私が期待していたもの:
11:15 enlil D:\Users\x> ls .gitconfig | sed "s/ */ /g"
Directory: D:\Users\x
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 6/23/2014 4:11 PM 56 .gitconfig
私の目標PowerShell によって追加された、データの列間の冗長なスペースを削除します。面白いことに、これは 1 台のコンピューター (Win8.1 搭載) では完全に機能しますが、Win7 搭載の別のコンピューターでは機能しません。
そして、より単純な例でも機能します:
11:49 enlil D:\Users\x> echo "t a t" | sed "s/ */ /g"
t a t
どのような助けでも大歓迎です。
ご参考までに -Get-ChildItemsの通常の出力次のようになります:
11:22 enlil D:\Users\x> ls .gitconfig
Directory: D:\Users\x
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 6/23/2014 4:11 PM 56 .gitconfig
答え1
それは Unicode です。sed から出力されるものは、PowerShell が Unicode と ASCII を区別するために使用する 2 バイトのプレフィックスのない Unicode です。そのため、PowerShell はそれを ASCII とみなし、\0 バイト (2 バイト Unicode 文字の上位バイト) を残します。これは空白として表示されます。また、PowerShell は内部的に Unicode を扱うため、実際には元のバイトすべてを 2 バイトの Unicode 文字に拡張します。PowerShell に Unicode を受け入れるように強制する方法はありません。考えられる回避策は次のとおりです。
SED への入力として Unicode が使用されていますか? 可能性は低いですが、可能性はあると思います。確認してください。
SED の出力を Unicode インジケーター \uFEFF で開始します。これはおそらく SED ソース コードで抜け落ちているものです。
_setmode(_fileno(stdout), _O_WTEXT); // probably present and makes it send Unicode wprintf(L"\uFEFF"); // probably missing
SEDコマンド内に次のようなコードを追加できます。
sed "1s/^/\xFF\xFE/;..." # won't work if SED produces Unicode but would work it SED passes Unicode through from its input sed "1s/^/\uFEFF/;..." # use if SED produces Unicode itself, hopefully SED supports \u
sed の出力をファイルに書き込み、Get-Content -Encoding Unicode で読み取ります。ファイルへの切り替えは、次のように cmd.exe 内のコマンドで行う必要があることに注意してください。
cmd /c "sed ... >file"
>file を PowerShell で処理させると、同じように混乱が生じます。
PowerShell で結果のテキストから \0 文字を削除します。これは、コード 0xA または 0xD を含む Unicode バイトを作成する国際文字ではうまく機能しません。代わりに行分割が行われます。