【问题标题】:Where-Object, Select-Object and ForEach-object - Differences and UsageWhere-Object、Select-Object 和 ForEach-object - 区别和用法
【发布时间】:2019-10-19 15:17:08
【问题描述】:

Where-ObjectSelect-ObjectForEach-Object

我是 PowerShell 初学者。我不是太了解。谁能举例说明它们之间的区别和使用场景?

【问题讨论】:

  • help Where-Object ; help Select-Object ; help ForEach-Object
  • 具体使用场景?
  • 您需要阅读帮助。如果您指定 -full 参数,它将为您提供示例。例如:help ForEach-Object -full 将显示所有参数、参数集和示例。请务必运行Update-Help 以确保您的帮助文件是最新的。您可以随时运行help ForEach-Object -online 转到可能更新的在线页面。

标签: powershell


【解决方案1】:

如果您完全熟悉 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

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

Select-Object

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

Get-Process
Get-Process | Select-Object Name,CPU

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

ForEach-Object

就像您在其他语言中的 foreach 循环一样,具有自己的 important 风格。事实上,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
}

【讨论】:

  • 提高了答案,因为这帮助我以非常清晰的方式理解语义。谢谢。
【解决方案2】:

你有两件事:过滤和遍历集合。

  1. 过滤: 原则:始终尽可能使用左过滤。这两个命令做同样的事情,但第二个不会通过管道(或网络)传输大量数据:

获取进程 | where-Object {$_.Name -like 'chrome'} | |导出-CSV 'c:\temp\processes.csv'

Get-Process -Name chrome |导出-CSV c:\temp\processes.csv

这在处理大量计算机或大文件时非常有用。

许多命令行开关都有自己的过滤功能。运行 get Get-Help get-process -full 在管道之前查看他们提供的内容。

  1. 遍历集合

这里有 3 种可能性:

  • batch cmdlet 是内置的命令行开关,可以将集合传递给另一个命令行开关:

Get-Service -name BITS,Spooler,W32Time |设置服务-启动类型 自动

  • WMI 方法 - WMI 使用它自己的方式来做第一个(不同的语法)

gwmi win32_networkadapterconfiguration -filter "描述如 '%intel%'" | 启用DHCP()

  • 枚举对象 - 遍历列表:

Get-WmiObject Win32_Service -filter "name = 'BITS'" | ForEach-对象 -进程 { $_.change($null,$null,$null,$null,$null,$null,$null,"P@ssw0rd") }

学分: 我在一本名为在一个月的午餐中学习 Powershell(在本例中为第 9 章和第 13 章)的书中找到了解决所有这些问题的解释。

【讨论】:

    猜你喜欢
    • 2012-07-19
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多