GnuWin32 / sed неожиданное поведение в Powershell

GnuWin32 / sed неожиданное поведение в Powershell

Я используюGnuWin32инструменты в командной строке Windows/Powershell.

Что видно:

 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. Забавно, что это отлично работает на одном компьютере (с 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, — это Unicode без 2-байтового префикса, который PowerShell использует для различения Unicode и ASCII. Поэтому PowerShell думает, что это ASCII, и оставляет байты \0 (верхние байты 2-байтовых символов Unicode), которые отображаются как пустые. И поскольку PowerShell работает с Unicode, он фактически расширяет каждый исходный байт до 2-байтового символа Unicode. Невозможно заставить PowerShell принять Unicode. Возможные способы обойти это:

  1. Будет ли Unicode входить в SED? Маловероятно, но я думаю, что это возможно. Проверьте это.

  2. Сделайте вывод 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
    
  3. Запишите вывод sed в файл, а затем прочитайте с помощью Get-Content -Encoding Unicode. Обратите внимание, что переключение на файл должно быть выполнено в команде внутри cmd.exe, например:

    cmd /c "sed ... >file"
    

    Если вы просто позволите обрабатывать >file в PowerShell, все будет так же плохо.

  4. Удалите символы \0 из полученного текста в PowerShell. Это не очень хорошо работает с международными символами, которые создают байты Unicode, содержащие код 0xA или 0xD — вместо них вы получаете разрывы строк.

Связанный контент