GnuWin32/sed comportamiento inesperado en Powershell

GnuWin32/sed comportamiento inesperado en Powershell

estoy usandoGnuWin32herramientas en la línea de comandos de Windows/Potencia Shell.

Qué se ve:

 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

Lo que esperaba ver:

 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

Mi objetivoes deshacerse de los espacios redundantes entre columnas de datos, que se agregan mediante PowerShell. Lo curioso es que esto funciona perfectamente en una computadora (con Win8.1), pero no funciona en otra computadora con Win7.

Y funciona para ejemplos más simples:

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

Cualquier ayuda será muy apreciada.

Para su información -Salida normal de Get-ChildItemsSe ve como esto:

 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

Respuesta1

Es el Unicode. Lo que sale de sed es Unicode sin el prefijo de 2 bytes que usa PowerShell para diferenciar entre Unicode y ASCII. Entonces, PowerShell piensa que es ASCII y deja los \0 bytes (los bytes superiores de los caracteres Unicode de 2 bytes), que se muestran en blanco. Y dado que internamente PowerShell trabaja con Unicode, en realidad expande cada byte original a un carácter Unicode de 2 bytes. No hay forma de obligar a PowerShell a aceptar Unicode. Las posibles formas de evitarlo son:

  1. ¿Unicode viene como entrada a SED? Es poco probable pero creo que es posible. Mira esto.

  2. Haga que la salida de SED comience con el indicador Unicode, \uFEFF. Probablemente esto es lo que se perdió en el código fuente de SED:

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

    Puede agregar el código dentro del comando SED, algo como

    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. Escriba la salida de sed en un archivo y luego léala con Get-Content -Encoding Unicode. Tenga en cuenta que el cambio al archivo debe realizarse con el comando dentro de cmd.exe, como:

    cmd /c "sed ... >file"
    

    Si simplemente deja que el archivo se maneje en PowerShell, se estropeará de la misma manera.

  4. Suelte los caracteres \0 del texto resultante en PowerShell. Esto no funciona bien con los caracteres internacionales que crean los bytes Unicode que contienen el código 0xA o 0xD; terminas con divisiones de línea en lugar de ellas.

información relacionada