PowerShell $_ 语法

PowerShell $_ syntax

作者在 this answer 中提出了以下代码段:

dir -Path C:\FolderName -Filter *.fileExtension -Recurse | %{$_.FullName}

我能理解其中的大部分内容,但我无法搜索最后一部分的文档。搜索的输出通过管道传输 | 并用于 %{}$_.

我已经围绕它进行了试验,%{} 是我认为的 for-each 语句,bing search was not effective. $_ is also somewhat magic: it is a variable, with no name and thus immediately consumed? I don't care much for the .FullName, that part I sorted out. Again, bing search was not effective,也没有在 PowerShell 文档中搜索那些字符序列。

有人能给我解释一下吗?

%{} 不是“一件事”——它是两件事:%{}

%ForEach-Object cmdlet:

的别名
PS ~> Get-Alias '%'
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           % -> ForEach-Object

...所以它解析为:

... |ForEach-Object { $_.FullName }

ForEach-Object 基本上是 PowerShell 的 map function - 它通过管道获取输入并将 {} 块中描述的操作应用于每个输入。

$_是对当前正在处理的管道输入项的自动引用

你可以把它想象成一个 foreach($thing in $collection){} 循环:

1..10 |ForEach-Object { $_ * 10 }
# produces the same output as
foreach($n in 1..10){
    $n * 10
}

除了我们现在可以将循环放在管道中间并让它产生输出以供立即使用:

1..10 |ForEach-Object { $_ * 10 } |Do-SomethingElse

ForEach-Object 并不是 PowerShell 中唯一使用 $_ 自动变量的东西——它还用于管道绑定表达式:

mkdir NewDirectory |cd -Path { $_.FullName }

... 以及 属性 表达式 ,一种动态 属性 定义,由许多 cmdlet 支持,例如 Sort-Object :

1..10 |Sort-Object { -$_ } # sort in descending order without specifying -Descending

...Group-Object:

1..10 |Group-Object { $_ % 3 } # group terms by modulo congruence

... 和 Select-Object:

1..10 |Select-Object @{Name='TimesTen';Expression={$_ * 10}} # Create synthetic properties based on dynamic value calculation over input 

为了补充 ,它很好地解释了具体的结构,你怎么可能/不可能自己发现这些信息,使用 PowerShell 自己的帮助系统:

相关帮助主题和帮助系统的使用:

注意:要获得 PowerShell 帮助系统各个方面的概述,只需运行help .

  • %ForEach-Object cmdlet 的内置 alias

    • 使用Get-Help ForEach-Object在终端查看帮助主题。
      • 如果找不到本地主题,您必须通过 Update-Help cmdlet 下载它们。
    • 小贴士:
      • 添加 -Online 开关以在浏览器中打开主题的(可能更新的)online version

      • 您可以 bootstrap 将 Get-HelpGet-Help Get-Help(甚至 help help)一起使用:

        • 特定于 Cmdlet 的帮助以 详细级别 提供:简洁(默认,仅显示语法和概述描述),-Detailed(包括参数描述和示例命令)和-Full(另外包括技术参数信息和扩展注释)。
        • -Examples 只能用于显示示例命令。
        • 使用基于关键字的搜索(见下文),您可以使用 -Category 参数将结果限制为特定类别的主题。
      • 为方便起见,您还可以使用内置的help函数,它用显示分页包装Get-Help调用(简单地说:通过管道输出到 more 实用程序)并默认为详细级别 -Full.

  • {...}是一个script block literal,可以按需调用的任意PowerShell代码块:

    • help about_Script_Blocks 显示本地主题; about_ 前缀表示该主题是一个 概念性 帮助主题(而不是涵盖特定命令的主题);当您使用 Get-Help 搜索关键字(见下文)时,您可以(有点模糊地)使用 -Category HelpFile.
    • 将结果限制为概念性主题
    • 注意:在撰写本文时,about_ 主题可以 不能 通过添加 -Online 直接在线查看 - 请参阅 GitHub issue #13550 -但很容易 google 他们的名字。
  • $_ 是一个 variable, as the $ sigil followed by an identifier implies, and is more specifically an automatic (built-in) variable:

    • help about_Variables 涵盖一般变量。
    • help about_Automatic_Variables涵盖自动的。

如何仅根据符号和别名可以/不能发现以上内容:

众所周知,在网络上搜索符号毫无帮助。

  • 顺便说一句:运行 不同的语法结构,例如 %{ ... } 之间没有空格(例如 %{$_.FullName})构成了一个额外的障碍,并且应该因此要避免。

仅使用 PowerShell 的帮助系统缩小搜索范围会有所帮助,但程度有限:

  • %

    • 因为Get-Help知道别名,help %实际上工作正常并直接显示ForEach-Object的帮助主题。
    • help % -Examples 显示示例命令,包括使用脚本块和自动 $_ 变量。
  • 即使Get-Help支持基于关键字的搜索搜索基于符号 术语 {}$_ 直接 没有帮助,因为即使限制使用 -Category HelpFile 搜索 概念about_-前缀主题),要么点击次数太多(help '$_' -Category HelpFile),要么相关主题没有'完全不显示 (help '{}' -Category HelpFile)

  • $_ 可以 间接发现 ,如果您已经知道它是 变量 [=209] 的实例=]:

    • help variables -Category HelpFile 恰好将您直接带到相关的(本地)about_Automatic_Variables 主题,
    • help variable -Category HelpFile 列出 以下匹配主题 about_Variable_Provider、``、about_Automatic_Variablesabout_Preference_Variablesabout_Remote_Variablesabout_Variablesabout_Environment_Variables
    • 注意:由于 PowerShell 对 wildcard expressions 的普遍支持,您也可以按如下方式执行搜索:help about*variable* - 请务必将 * 中搜索词的两侧。
  • $_ 可以 间接发现 ,如果您已经知道它是脚本(代码)的实例 区块:


未来可能的改进:

  • 如果 PowerShell 的帮助系统支持基于 symbol 的集中搜索,那将是一个很大的改进。

  • 同样,如果能够直接查找运算符,例如-matchregular-expression matching operator,将会很有帮助:

    • GitHub issue #11339 就是这样提议的。

    • 在相关说明中,GitHub issue #11338 建议添加查找 .NET 类型(在线)文档的功能。

    • 包含自定义函数 Show-OperatorHelpShow-TypeHelp,它们暂时填补了这个空白(也可作为 Gists 使用)。