![Powershell 中的 GnuWin32 / sed 意外行为](https://linux22.com/image/1428756/Powershell%20%E4%B8%AD%E7%9A%84%20GnuWin32%20%2F%20sed%20%E6%84%8F%E5%A4%96%E8%A1%8C%E4%B8%BA.png)
我在用操作系统Windows 命令行上的工具/电源外壳。
看到的是:
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,没有 PowerShell 用来区分 Unicode 和 ASCII 的 2 字节前缀。因此,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 中处理,它就会以同样的方式变得混乱。
从 PowerShell 中的结果文本中删除 \0 字符。这对于创建包含代码 0xA 或 0xD 的 Unicode 字节的国际字符不起作用 - 您最终会得到行分割而不是它们。