Я использую инструменты 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 ответ1

2

Это Юникод. В основе 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"
    

    Если вы просто разрешите> обрабатывать файл в PowerShell, он будет испорчен таким же образом.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .