![GnuWin32 / sed неожиданное поведение в Powershell](https://rvso.com/image/1428756/GnuWin32%20%2F%20sed%20%D0%BD%D0%B5%D0%BE%D0%B6%D0%B8%D0%B4%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5%20%D0%BF%D0%BE%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B2%20Powershell.png)
Я использую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. Возможные способы обойти это:
Будет ли Unicode входить в SED? Маловероятно, но я думаю, что это возможно. Проверьте это.
Сделайте вывод 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
Запишите вывод sed в файл, а затем прочитайте с помощью Get-Content -Encoding Unicode. Обратите внимание, что переключение на файл должно быть выполнено в команде внутри cmd.exe, например:
cmd /c "sed ... >file"
Если вы просто позволите обрабатывать >file в PowerShell, все будет так же плохо.
Удалите символы \0 из полученного текста в PowerShell. Это не очень хорошо работает с международными символами, которые создают байты Unicode, содержащие код 0xA или 0xD — вместо них вы получаете разрывы строк.