Where-Object、Select-Object 和 ForEach-object - 差异和用法

tia*_*nyi 4 powershell

Where-ObjectSelect-ObjectForEach-Object

我是 PowerShell 初学者。我不太明白。有人可以举例说明它们之间的区别和使用场景吗?

小智 9

如果您非常熟悉 LINQ 或 SQL,那么它应该更容易理解,因为它对相同的单词使用相同的概念,并稍作调整。

Where-Object

用于从管道中过滤掉对象,类似于 SQL 过滤行的方式。此处,将对象与条件(或可选的条件)进行比较ScriptBlock,以确定是否应将其传递到管道中的下一个 cmdlet。展示:

# Approved Verbs
Get-Verb | Measure-Object # count of 98
Get-Verb | Where-Object Verb -Like G* | Measure-Object # 3

# Integers 1 to 100
1..100 | Measure-Object # count of 100
1..100 | Where-Object {$_ -LT 50} | Measure-Object # count of 49
Run Code Online (Sandbox Code Playgroud)

当不使用 a时,此语法通常是最具可读性的ScriptBlock,但如果您想引用对象本身(而不是属性)或更复杂的布尔结果,则此语法是必要的。注意:许多资源会建议(如 @ Iftimie Tudor提到的)尝试在管道中更快(更左)进行过滤以获得性能优势。

Select-Object

用于过滤对象的属性,类似于 SQL 过滤列的方式。重要的是,它将管道对象转换为一个新对象PSCustomObject,该对象仅具有所请求的属性以及复制的对象值。展示:

Get-Process
Get-Process | Select-Object Name,CPU
Run Code Online (Sandbox Code Playgroud)

但请注意,这只是标准用法。使用它Get-Help Select-Object具有类似行式过滤功能的地方探索其参数集,例如仅从管道(也称为Get-Process | Select-Object -First 3)中获取前 n 个对象,然后继续到下一个 cmdlet。

ForEach-Object

就像foreach其他语言中的循环一样,有其自己的重要风格。事实上,PowerShell 也有foreach自己的循环!这些可能很容易混淆,但在操作上却截然不同。主要的视觉差异是foreach循环不能在管道中使用,但ForEach-Object可以。后者ForEach-Object是一个 cmdlet(foreach不是),可用于转换当前管道或针对管道运行一段代码。它确实是最灵活的 cmdlet。

考虑它的最佳方式是,它是一个循环体,其中当前元素 ,$_来自管道,并且任何输出都会传递到下一个 cmdlet。展示:

# Transform
Get-Verb | ForEach-Object {"$($_.Verb) comes from the group $($_.Group)"}
# Retrieve Property
Get-Verb | ForEach-Object Verb
# Call Method
Get-Verb | ForEach-Object GetType
# Run Code
1..100 | ForEach-Object {
    $increment = $_ + 1
    $multiplied = $increment * 3
    Write-Output $multiplied
}
Run Code Online (Sandbox Code Playgroud)