GnuWin32 / sed unerwartetes Verhalten in Powershell

GnuWin32 / sed unerwartetes Verhalten in Powershell

ich benutzeGnuWin32Tools in der Windows-Befehlszeile/Power Shell.

Was ist zu sehen:

 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

Was ich erwartet hatte zu sehen:

 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

Mein Zieldient dazu, redundante Leerzeichen zwischen Datenspalten zu entfernen, die von PowerShell hinzugefügt werden. Interessanterweise funktioniert dies auf einem Computer (mit Win8.1) einwandfrei, auf einem anderen Computer mit Win7 jedoch nicht.

Und es funktioniert für einfachere Beispiele:

 11:49 enlil D:\Users\x> echo "t  a t" |  sed "s/ */ /g"
 t a t

Jede Hilfe wird sehr geschätzt.

Zu Ihrer Information -Normale Ausgabe von Get-ChildItemssieht aus wie das:

 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

Antwort1

Es ist Unicode. Das Zeug, das aus sed kommt, ist Unicode ohne das 2-Byte-Präfix, das PowerShell verwendet, um zwischen Unicode und ASCII zu unterscheiden. PowerShell denkt also, es sei ASCII und lässt die \0-Bytes (die oberen Bytes von 2-Byte-Unicode-Zeichen) drin, die als Leerzeichen angezeigt werden. Und da PowerShell intern mit Unicode arbeitet, erweitert es tatsächlich jedes ursprüngliche Byte in ein 2-Byte-Unicode-Zeichen. Es gibt keine Möglichkeit, PowerShell dazu zu zwingen, Unicode zu akzeptieren. Die möglichen Umgehungsmethoden sind:

  1. Wird Unicode als Eingabe in SED verwendet? Unwahrscheinlich, aber ich denke, es ist möglich. Überprüfen Sie das.

  2. Lassen Sie die Ausgabe von SED mit dem Unicode-Indikator \uFEFF beginnen. Dies wurde im SED-Quellcode wahrscheinlich übersehen:

    _setmode(_fileno(stdout), _O_WTEXT); // probably present and makes it send Unicode
    wprintf(L"\uFEFF"); // probably missing
    

    Sie können den Code in den SED-Befehl einfügen, etwa so:

    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
    
  3. Die Ausgabe von sed in eine Datei schreiben und dann mit Get-Content -Encoding Unicode lesen. Beachten Sie, dass der Wechsel in die Datei im Befehl innerhalb von cmd.exe erfolgen muss, etwa so:

    cmd /c "sed ... >file"
    

    Wenn Sie die Datei einfach in PowerShell handhaben lassen, kommt es zu demselben Durcheinander.

  4. Entfernen Sie die Zeichen \0 aus dem resultierenden Text in PowerShell. Dies funktioniert nicht gut mit den internationalen Zeichen, die die Unicode-Bytes mit dem Code 0xA oder 0xD erstellen. Stattdessen erhalten Sie die Zeilenumbrüche.

verwandte Informationen