补充Theo's helpful answer:
tl;dr:
# Note the use of -PipelineVariable obj and the use of $obj later.
PS> Write-Output -PipelineVariable obj (
[pscustomobject] @{ Brand = 'Volkswagen'; Model = 'Passat' },
[pscustomobject] @{ Brand = 'Ford'; Model = 'Mondeo' }
) |
Select-String -SimpleMatch wagen |
ForEach-Object { $obj.psobject.Properties.Value -join ', ' }
Volkswagen, Passat
Write-Output 命令只是在代码中为Select-String 生成输入对象的实际命令的替代,例如Import-Csv。
-
您的Select-String 输出意味着[pscustomobject] 实例用作其输入,例如Import-Csv 的输出。
- 例如,您的输出暗示了一个输入对象,例如
[pscustomobject] @{ Brand = 'Volkswagen'; Model = 'Passat' }
-
正如 Theo 所说,Select-String 旨在对 字符串 进行操作,而不是对 具有属性的对象。
-
当Select-String 收到此类对象时,它会为它们创建一个字符串 表示并搜索那个。
-
使这特别无用的是,此字符串表示不与您在 终端(控制台)中看到的相同,其中使用了 PowerShell 丰富的输出格式;相反,执行简单的.ToString() 字符串化,这与[pscustomobject] 实例一起导致诸如'@{Brand=Volkswagen; Model=Passat}' 之类的表示(可能令人困惑,这类似于- 但不同于- 哈希表文字)。
-
此外,如果您确实让Select-String 对此类对象进行操作,则其输出(Microsoft.PowerShell.Commands.MatchInfo 实例)不再包含输入对象 em>,仅它们的字符串表示,这意味着为了提取值Volkswagen 和Passat,您必须执行字符串解析,即既麻烦又不健壮。
要根据属性值过滤具有属性的输入对象,Where-Object 是更好的选择;例如:
PS> [pscustomobject] @{ Brand = 'Volkswagen'; Model = 'Passat' },
[pscustomobject] @{ Brand = 'Ford'; Model = 'Mondeo' } |
Where-Object Brand -eq Volkswagen
Brand Model
----- -----
Volkswagen Passat
也就是说,使用Select-Object 仍然会有所帮助如果您不知道输入对象具有哪些属性,并且想在对象,通过它的 string 表示:
PS> [pscustomobject] @{ Brand = 'Volkswagen'; Model = 'Passat' },
[pscustomobject] @{ Brand = 'Ford'; Model = 'Mondeo' } |
Select-String -SimpleMatch wagen
@{Brand=Volkswagen; Model=Passat}
以上是您尝试过的,但如前所述,这实际上只输出整个对象的字符串表示形式,之后没有(简单)提取属性值的能力。
解决方案是在输入对象生成命令上使用common -PipelineVariable parameter,它允许在稍后管道段的 (ForEach-Object) 脚本块中访问手头的对象,这允许您轻松创建所需的以逗号分隔的属性值列表(即使不知道属性名称):
# Note the use of -PipelineVariable obj and the use of $obj later.
PS> Write-Output -PipelineVariable obj (
[pscustomobject] @{ Brand = 'Volkswagen'; Model = 'Passat' },
[pscustomobject] @{ Brand = 'Ford'; Model = 'Mondeo' }
) |
Select-String -SimpleMatch wagen |
ForEach-Object { $obj.psobject.Properties.Value -join ', ' }
Volkswagen, Passat
$obj.psobject.Properties.Value 使用 PowerShell 为所有对象提供的隐藏的、内在的 .psobject 属性,这是 反射 的丰富来源,在这种情况下,可以通过 @ 轻松访问所有属性值987654330@.