Powershell Select-Object 与 ForEach 在 Select-String 结果上的比较

发布于 2024-12-03 22:04:15 字数 1352 浏览 1 评论 0原文

假设我在变量 $mat 中调用 Select-String 的结果,从文件内容解析正则表达式:

$mat = cat errors.txt | Select-String "'(?<code>\w+)'.+ID (?<id>[^:]+)" 

根据 $mat | 的输出Get-Member 结果包含 Match[] 类型的 Matches 属性。

当我执行以下命令时,我得到了正则表达式输出的所有匹配项:

PS > $mat | Select-Object -Property Matches

Matches                                                                                                                                                                              
-------                                                                                                                                                                              
{'ACCFWD', ID 16}                                                                                                                                                                    
{'EQASIAN', ID 448}                   
    

为什么使用 foreach 选择匹配项的下一个代码块没有相同的输出:

    PS > $mat | ForEach { $_.Matches } 


Groups   : {'ACCFWD', ID 16, ACCFWD, 16}
Success  : True
Captures : {'ACCFWD', ID 16}
Index    : 20
Length   : 15
Value    : 'ACCFWD', ID 16

Groups   : {'EQASIAN', ID 448, EQASIAN, 448}
Success  : True
Captures : {'EQASIAN', ID 448}
Index    : 20
Length   : 17
Value    : 'EQASIAN', ID 448

Let's say I have the results of a call to Select-String in a variable $mat, parsing a regular expression from file contents:

$mat = cat errors.txt | Select-String "'(?<code>\w+)'.+ID (?<id>[^:]+)" 

According to the output of $mat | Get-Member the result contains a Matches property of type Match[].

When I execute the following I get all the matches of my regular expression output:

PS > $mat | Select-Object -Property Matches

Matches                                                                                                                                                                              
-------                                                                                                                                                                              
{'ACCFWD', ID 16}                                                                                                                                                                    
{'EQASIAN', ID 448}                   
    

Why doesn't this next block of code using foreach to select the Matches have the same output:

    PS > $mat | ForEach { $_.Matches } 


Groups   : {'ACCFWD', ID 16, ACCFWD, 16}
Success  : True
Captures : {'ACCFWD', ID 16}
Index    : 20
Length   : 15
Value    : 'ACCFWD', ID 16

Groups   : {'EQASIAN', ID 448, EQASIAN, 448}
Success  : True
Captures : {'EQASIAN', ID 448}
Index    : 20
Length   : 17
Value    : 'EQASIAN', ID 448

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风蛊 2024-12-10 22:04:15

显示属性时,PowerShell 会将 *.format.ps1xml 文件中未定义显示格式的类型的属性自动格式化为最多包含 4 个属性的表格。 5 个或更多属性显示为列表。当您使用 Select-Object 选择 Matches 属性时,您正在选择 Microsoft.PowerShell.Commands.MatchInfo 对象的单个属性。使用Foreach-Object,您可以显示System.Text.RegularExpressions.Match 对象的所有属性。

使用 Select-Object -ExpandProperty Matches 将使输出看起来与 Foreach 相同,因为它将输出 RegularExpressions.Match 对象。

如果将 Get-Member 放置在两个生成输出的示例之后,您将看到它们输出不同类型的对象。

编辑:以下是对每个命令发生的格式的说明。

cat errors.txt | Select-String "'(?<code>\w+)'.+ID (?<id>[^:]+)"

Select-String 的输出是一个 Microsoft.PowerShell.Commands.MatchInfo 对象,它有 8 个属性。默认情况下不会显示这些属性,因为 MatchInfo 的显示格式是在 PowerShellCore.format.ps1xml 中定义的,用于显示 MatchInfo 的结果ToString() 方法。

$mat | Select-Object -Property Matches

在本例中,Select-Object 的输出是一个自定义 Selected.Microsoft.PowerShell.Commands.MatchInfo 对象,其 Matches 属性为从 MatchInfo 对象复制。由于没有为 Selected.Microsoft.PowerShell.Commands.MatchInfo 类型定义默认显示格式,PowerShell 会自动将其格式化为表格,因为它的属性少于 5 个(在本例中 Matches 是唯一的属性)。

$mat | ForEach { $_.Matches } 

Foreach-Object ScriptBlock 中,正在输出 MatchInfo 对象的 Matches 属性。 Matches 属性是一个 System.Text.RegularExpressions.Match,它有 6 个属性。由于没有为 System.Text.RegularExpressions.Match 类型定义默认显示格式,因此 Match 对象将显示为列表,因为属性超过 4 个。

When displaying properties, PowerShell auto-formats the properties of types that do not have a display format defined in a *.format.ps1xml file as a table for up to 4 properties. 5 or more properties displays as a list. When you select the Matches property with Select-Object, you are selecting a single property of the Microsoft.PowerShell.Commands.MatchInfo object. With Foreach-Object you are displaying all of the properties for a System.Text.RegularExpressions.Match object.

Using Select-Object -ExpandProperty Matches will cause the output to look the same as the Foreach because it will output RegularExpressions.Match objects.

If you place Get-Member after both of your examples that produce output you will see that they output different types of objects.

Edit: Here is an explanation of the formatting that happens for each command.

cat errors.txt | Select-String "'(?<code>\w+)'.+ID (?<id>[^:]+)"

The output of Select-String is a Microsoft.PowerShell.Commands.MatchInfo object which has 8 properties. These properties are not displayed by default because the display format for MatchInfo is defined in PowerShellCore.format.ps1xml to show the result of MatchInfo's ToString() method.

$mat | Select-Object -Property Matches

In this case, the output of Select-Object is a custom Selected.Microsoft.PowerShell.Commands.MatchInfo object with the Matches property that was copied from the MatchInfo object. Since there is no default display format defined for the Selected.Microsoft.PowerShell.Commands.MatchInfo type, PowerShell auto formats it as a table since it has less than 5 properties (In this case Matches is the only property).

$mat | ForEach { $_.Matches } 

In the Foreach-Object ScriptBlock, the Matches property of the MatchInfo object is being output. The Matches property is a System.Text.RegularExpressions.Match which has 6 properties. Since there is no default display format defined for the System.Text.RegularExpressions.Match type, the Match objects are displayed as a list because there are more than 4 properties.

嗼ふ静 2024-12-10 22:04:15

如果您使用 -ExpandProperty 而不是 -Property,则两个输出将相同。

$mat | Select-Object -ExpandProperty Matches

这适用于这个特定的示例,但对于访问单个属性,Select-Object -ExpandProperty 在所有情况下仍然与 ForEach 不完全相同。我会使用 ForEach。另请参阅此示例: http://community.idera.com/powershell/powertips/b/tips/posts/use-foreach-object-instead-of-select-object-expandproperty

If you use -ExpandProperty instead of -Property, then the two outputs will be the same.

$mat | Select-Object -ExpandProperty Matches

That works for this particular example, but for accessing a single property, Select-Object -ExpandProperty is still not exactly the same as ForEach in all cases. I would use ForEach. Also, see this example: http://community.idera.com/powershell/powertips/b/tips/posts/use-foreach-object-instead-of-select-object-expandproperty

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文