GnuWin32 / sed comportamento inesperado em Powershell

0

Estou usando as ferramentas GnuWin32 na linha de comando do Windows / PowerShell .

O que você vê:

 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

O que eu esperava 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

Meu objetivo é livrar-se de espaços redundantes entre colunas de dados, que são adicionados pelo PowerShell. Engraçado é que isso funciona perfeitamente em um computador (com Win8.1), mas não funciona em outro computador com Win7.

E funciona para exemplos mais simples:

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

Qualquer ajuda será muito apreciada.

FYI - A saída normal de Get-ChildItems é semelhante a:

 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
    
por mnmnc 29.10.2014 / 11:35

1 resposta

2

É o Unicode. O material que sai do sed é Unicode sem o prefixo de 2 bytes que o PowerShell usa para diferenciar entre Unicode e ASCII. Portanto, o PowerShell acha que é ASCII e deixa os bytes \ 0 (os bytes superiores dos caracteres Unicode de 2 bytes), que são exibidos como espaços em branco. E como internamente o PowerShell lida com Unicode, ele realmente expande cada byte original em um caractere Unicode de 2 bytes. Não é possível forçar o PowerShell a aceitar o Unicode. As possíveis maneiras de contornar isso são:

  1. O Unicode vem como entrada para o SED? Improvável, mas acho possível. Verifique isso.

  2. Faça a saída do SED iniciar com o indicador Unicode, \ uFEFF. Isso é provavelmente o que ficou perdido no código-fonte do SED:

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

    Você pode adicionar o código dentro do 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. Grave a saída de sed em um arquivo e, em seguida, leia com Get-Content -Encoding Unicode. Note que a mudança para o arquivo deve ser feita no comando dentro do cmd.exe, como:

    cmd /c "sed ... >file"
    

    Se você permitir que o arquivo > seja manipulado no PowerShell, ele será desarrumado da mesma maneira.

  4. Elimine os caracteres \ 0 do texto resultante no PowerShell. Isso não funciona bem com os caracteres internacionais que criam os bytes Unicode contendo código 0xA ou 0xD - você acaba com os divisões de linha em vez deles.

por 03.03.2015 / 23:56