json - out-string 和 toString() 创建的字符串对象有区别吗?
问题描述
我正在解析 json 文件中的一些文本,并基于我想要对文本执行操作的文本。
foreach ($jsonText in $jsonFile.row[0]){
$stringA = $jsonText.ToString()
$stringB = $jsonText| Out-String
switch ($stringA)
{
'A' {'do things'}
'B' {'do other things'}
'C' {'do somethings'}
}
来自管道输出字符串的字符串不会产生可以在开关盒中使用的字符串,所以我想知道这两个字符串是否有区别?
解决方案
根本区别在于,它使用
Out-String
PowerShell 丰富的显示输出格式化系统来处理非字符串、非原始对象,而.ToString()
只是将字符串化委托给手头的 .NET 类型(除非被类型覆盖,否则只会报告完整的输入名称)。- 换句话说:
Out-String
默认情况下,创建一个单行的多行字符串,该字符串具有与您在控制台中看到的相同的格式丰富的、供人类观察者使用的表示。 - 添加通过管道逐行
-Stream
发送此表示(如果在变量中捕获,则会产生行数组)。鉴于复杂对象的表示是多行的并且以表格形式共享一个标题,单行不对应于单个输入对象。
- 换句话说:
从 PowerShell 7.2 开始,(without )的一个不幸方面是它会在输出格式系统报告的任何内容中附加一个尾随换行符
Out-String
-Stream
,这也适用于作为输入的字符串,否则 PowerShell 的格式系统会按原样表示;同样,.NET 原始类型和一些单值类型由它们的.ToString()
返回值表示。- GitHub 问题 #14444讨论了这种有问题的行为。
# Unfortunately, these equivalences are true.
# With a single input object, adding -Stream would avoid the trailing newline.
('foo'.ToString() + [Environment]::NewLine) -eq ('foo' | Out-String)
((42).ToString() + [Environment]::NewLine) -eq (42 | Out-String)
的用途Out-String
如果您明确需要 PowerShell 格式化系统生成的丰富的用于显示的表示形式的字符串表示形式,请使用它。
与 结合使用
-Stream
,这可以作为一种快速而简单的方式来通过命令的显示输出进行搜索Select-String
;PowerShell 甚至附带了oss
包装的函数 ,Output-String -Stream
因此您可以执行以下操作:# Quick-and-dirty search through the formatted representations # of all defined drives, without having to worry about property names. Get-PSDrive | oss | Select-String \\server1
遗憾的是,默认情况下
Select-String
不会搜索格式化的表示形式(在这种情况下,您可以省略调用),即使这很有意义(它实际上是搜索通常无用的表示形式)。oss
.ToString()
- GitHub 问题 #10726建议更改默认行为。
使用外部程序,您可以使用它将它们的输出行(PowerShell 总是将其解释为文本(字符串))连接成单多行字符串。
例如,要从
tzutil /l
单个多行字符串中获取输出:$output = tzutil /l | Out-String
不幸的是,这再次受到意外添加尾随换行符的阻碍,如GitHub 问题 #14444中所述;解决方法:
修剪尾随换行符,在最简单的情况下使用
.Trim()
$output = (tzutil /l | Out-String).Trim()
改为使用
-join
操作:$output = (tzutil /l) -join [Environment]::NewLine