0

我知道有很多关于扩展单个属性的帖子,希望这是一个简单的帖子,但是由于 select-string -simplematch,我的输出看起来像这样

@{品牌=大众; 型号=帕萨特}
@{品牌=福特;型号=蒙迪欧}

但是如何扩展这两个属性并使输出看起来像这样呢?

大众、帕萨特
福特、蒙迪欧

当我做一个选择对象 * 我得到以下但我似乎不能只得到值

IgnoreCase : True
Linenumber : 1
Line : @{Brand=Volkswagen; Model=Passat}
文件名:InputStream
路径:InputStream
模式:@{Brand=Volkwagen; 模型=帕萨特}
上下文:
匹配:{}}

IgnoreCase : True
Linenumber : 2
Line : @{Brand=Ford; Model=Mondeo}
文件名:InputStream
路径:InputStream
模式:@{Brand=Ford; 模型=蒙迪欧}
上下文:
匹配:{}}

4

3 回答 3

1

不要select-string在 PsObjects 集合上执行此操作,因为该 cmdlet 旨在查找字符串文件中的文本..
Select-Object -ExpandProperty允许您扩展一个属性,而不是全部。如果您想要这样的输出,请遍历数组中的对象并按照您想要的方式将属性组合成一个字符串。

假设你的数组是这样的:

$theCarCollection = [PsCustomObject]@{Brand='Volkswagen'; Model='Passat'},
                    [PsCustomObject]@{Brand='Ford'; Model='Mondeo'}

然后通过遍历对象并选择所需的属性来格式化输出

($theCarCollection | ForEach-Object { '{0}, {1}' -f $_.Brand, $_.Model }) -join [environment]::NewLine

这将输出:

Volkswagen, Passat
Ford, Mondeo
于 2021-03-03T12:49:44.427 回答
0

可能是这样的:

Select-String -Path "C:\temp\test.txt" -Pattern "test" | select line -ExpandProperty line
于 2021-03-03T12:39:25.393 回答
0

为了补充Theo 的有用答案

tl;博士

# 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}'(可能令人困惑的是,这类似于 - 但不同于 -哈希表文字)的表示。

  • 此外,如果您确实letSelect-String对此类对象进行操作,则其输出Microsoft.PowerShell.Commands.MatchInfo实例)不再包含输入对象,仅包含它们的字符串表示形式,这意味着为了提取值Volkswagenand 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定位一个值,则 using仍然会有所帮助:

PS> [pscustomobject] @{ Brand = 'Volkswagen'; Model = 'Passat' }, 
    [pscustomobject] @{ Brand = 'Ford'; Model = 'Mondeo' } |
      Select-String -SimpleMatch wagen

@{Brand=Volkswagen; Model=Passat}

以上是您尝试过的,但是,如前所述,这实际上只输出了整个对象的字符串表示,之后没有(容易)提取属性值的能力。

解决方案是在输入对象生成命令上使用common-PipelineVariable参数,它允许在稍后的管道段的 ( ) 脚本块中访问手头的对象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.psobject使用PowerShell 为所有对象提供的隐藏的内在属性,这是一个丰富的反射源,在这种情况下允许通过成员枚举轻松访问所有属性值。

于 2021-03-03T18:39:35.663 回答