【问题标题】:How can I prevent escape sequences being added to PowerShell output?如何防止将转义序列添加到 PowerShell 输出?
【发布时间】:2022-02-21 11:08:19
【问题描述】:

我没想到或不想要输出中的转义序列。第一行输出是:

0000000000000000 1B 5B 33 32 3B 31 6D 4C 6F 63 61 6C 41 64 64 72 �[32;1mLocalAddr

PS C:\src\t> Get-NetTCPConnection | Where-Object { $_.State -eq 'Established' } | Out-File -FilePath '.\task3.txt' -Encoding ascii
PS C:\src\t> Get-Content .\task3.txt -first 2 | Format-Hex

   Label: String (System.String) <5F8755A9>

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 1B 5B 33 32 3B 31 6D 4C 6F 63 61 6C 41 64 64 72 �[32;1mLocalAddr
0000000000000010 65 73 73 20 20 20 20 20 20 20 20 20 20 20 20 20 ess
0000000000000020 20 20 20 20 20 20 20 20 20 20 20 4C 6F 63 61 6C            Local
0000000000000030 50 6F 72 74 20 52 65 6D 6F 74 65 41 64 64 72 65 Port RemoteAddre
0000000000000040 73 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ss
0000000000000050 20 20 20 20 20 20 20 20 20 52 65 6D 6F 74 65 50          RemoteP
0000000000000060 6F 72 74 20 53 74 61 74 65 20 20 20 20 20 20 20 ort State
0000000000000070 41 70 70 6C 69 65 64 53 65 74 74 69 6E 67 20 4F AppliedSetting O
0000000000000080 77 6E 69 6E 67 50 72 6F 63 65 73 73 1B 5B 30 6D wningProcess**�[0m**

我注意到它没有出现在 Get-ChildItem 的输出中。

PS C:\src\t> dir *.g* | Out-File -FilePath '.\task5.txt' -Encoding ascii
PS C:\src\t> Get-Content -Path '.\task5.txt' -First 2 | Format-Hex

   Label: String (System.String) <5A0214B6>

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 20 20 20 20 44 69 72 65 63 74 6F 72 79 3A 20 43     Directory: C
0000000000000010 3A 5C 73 72 63 5C 74                            :\src\t

【问题讨论】:

  • 我的猜测,| Out-String + 删除所有 ANSI 转义字符,即:stackoverflow.com/a/45709053/15339544
  • | oss | &amp; { process { $_ -replace '\x1b\[[0-9;]*m' } } 似乎可以解决问题,但仍然不是理想的数据导出方式。
  • 通过 ANSI / VT 转义序列的彩色输出在 PowerShell 7.2+ 中使用。但是,dir == Get-ChildItem 使用它们,而不仅仅是 Get-NetTCPConnection

标签: powershell


【解决方案1】:

Tom's helpful answer 提出了重要的一点:Out-* cmdlet 的输出用于人类眼球,而不是用于编程处理

暂且不说:

ANSI / Virtual Terminal escape sequences - 在这种情况下用于生成 colored 输出 - 存在于您的输出文件中,这意味着您正在使用 PowerShell (Core) 7.2+,其中 $PSStyle.OutputRendering 的值决定了这些转义序列是在输出中保留 - 隐式还是显式- 调用Out-* cmdlet:

  • 使用$PSStyle.OutputRendering = 'Host' 将格式化输出中转义序列的使用限制为发送到显示器(主机/控制台/终端)的输出,并进行所有其他用途 - 将输出发送到带有&gt; 的文件(实际上是Out-File 的别名)或通过管道 - 导致删除这些转义序列以生成纯文本输出。

    • $PSStyle.OutputRendering = 'Host' 添加到您的 $PROFILE file 以将此行为作为未来会话的默认行为。
  • 遗憾的是,从 PowerShell 7.2.1 开始,$PSStyle.OutputRendering默认值为'Ansi'无条件在格式化输出中包含转义序列。 p>

    • 'Host' 将提供一个更明智的默认值,这与类 Unix 平台上 CLI 所表现出的行为一致,当其标准输出未连接到 终端时,它们本身会绕过转义序列的使用> - 除非明确要求包含它们,使用诸如 --color=always 之类的选项

【讨论】:

  • 那么,这是 7.2 中的新功能吗?这是否被认为是一个重大变化?我注意到这仅发生在标题行上,其下带有对象字段名称和连字符。 -Encoding 的规范似乎没有影响。我的控制台中的转义序列在视觉上没有任何影响; IE。没有颜色变化。我是否应该考虑将$PSStyle.OutputRendering = 'Host' 放入我的个人资料脚本之一?
  • @lit,不仅仅是标题;例如,Get-ChildItem 输出,项目根据文件系统项目类型着色;使用Select-String,每个输出行中与搜索模式匹配的部分会突出显示 - 如果您在终端中看不到颜色,请检查其配置。 -Encoding 参数与此行为完全无关。通常,对 for-display 输出格式的更改被视为重大更改。是的,如果您想限制使用转义序列来显示输出,将 $PSStyle.OutputRendering = 'Host' 放入您的 $PROFILE 是有意义的。
  • 你能告诉我们一个缺少转义序列会影响下游流程的例子吗?它在 7.2 文档中被列为“重大更改”。 docs.microsoft.com/en-us/powershell/scripting/whats-new/…
  • @lit,请注意该部分的标题不明确:“重大更改和改进”。我同意Ansi 是一个糟糕的默认值;并且它应该是HostAnsi 仅在您的意图是捕获格式化输出 as-is 时才有用,以便您可以稍后将其发送到显示器并获得与直接到 - 相同的颜色输出显示输出。
  • 您是否建议我们将该标题读作“重大更改或改进”? :-) 实际上,我不确定为什么这些项目不包含在包含重大更改的第一个列表中。我链接到的文档大约是 7.3。 $PSStyle 未在 docs.microsoft.com/en-us/powershell/scripting/whats-new/… 中提及
【解决方案2】:

“Out-File cmdlet 将输出发送到文件。它隐式使用 PowerShell 的格式化系统来写入文件。文件接收与终端相同的显示表示。这意味着输出可能不适合编程处理除非所有输入对象都是字符串。” - 来自documentation

当我在具有 IPV6 的系统上运行您的代码行时,这些地址会被截断,这可能是您可能没有发现的另一个缺点。

你没有说你最终想用这个文件做什么,但是export-csv 会产生更有用的结果:

Get-NetTCPConnection | Where-Object { $_.State -eq 'Established' } | export-csv '.\task3.txt'

【讨论】:

  • 当我使用dir *.g* | Out-File -FilePath '.\task5.txt' -Encoding ascii 时,列标题行周围没有转义序列。那是一个System.IO.FileInfo 对象。使用Get-NetTCPConnection 会产生一个Microsoft.Management.Infrastructure.CimInstance#ROOT/StandardCimv2/MSFT_NetTCPConnection 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多