【问题标题】:PowerShell $_ syntaxPowerShell $_ 语法
【发布时间】:2021-03-10 14:37:24
【问题描述】:

this answer作者提出了如下sn-p:

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

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

我已经围绕它进行了实验,%{} 是我相信的 for-each 语句,bing search was not effective$_ 也有点神奇:它是一个变量,没有名称,因此立即被消耗?我不太关心.FullName,我整理的那部分。同样,bing search was not effective,也不会在 PowerShell 文档中搜索这些字符序列。

谁能给我解释一下?

【问题讨论】:

  • 它表示沿管道传递的对象。这就是为什么您能够引用.Fullname 的属性。
  • 就像您将对象存储在变量中一样,例如:$Var = Get-Process -Name wuasrv 在这种情况下,我可以使用点表示法来引用对象属性:$Var.Name$_ 是相同的概念.它是传递的实际对象的占位符。

标签: powershell syntax pipe help-system


【解决方案1】:

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

%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 

【讨论】:

  • Visual Studio Code 的一个好处是,如果您安装了 powershell 插件,它会警告您使用别名并告诉您别名所指的内容。
【解决方案2】:

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

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

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

  • %ForEach-Object cmdlet 的内置 alias

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

      • 您可以使用Get-Help Get-Help(甚至help help)引导您对Get-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,正如$ sigil 后跟标识符所暗示的那样,更具体地说是automatic (built-in) variable

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

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

众所周知,在网络上搜索符号是没有帮助的。

  • 顺便说一句:将 %{ ... } 等不同的语法结构一起运行,而它们之间没有空格(例如 %{$_.FullName})会构成额外的障碍,因此应该避免。

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

  • %

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

  • $_ 可以发现间接,如果你已经知道它是一个变量的实例

    • 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* - 务必将 两边 括起来* 中的搜索词。
  • $_ 可以被发现间接,如果你已经知道它是一个脚本(代码)的实例block


未来可能的改进:

  • 如果 PowerShell 的帮助系统支持基于符号的重点搜索,那将是一个很大的改进。

  • 同样,直接查找运算符(例如-matchregular-expression matching operator)的能力也会有所帮助:

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

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

    • This answer 包含自定义函数 Show-OperatorHelpShow-TypeHelp,它们暂时填补了这一空白(也可作为 Gists 提供)。

【讨论】:

  • 我会给这个+2。网络搜索(尤其是在 MS 系统上......)可以提供更多帮助。我不知道帮助功能,PowerShell对我来说还是很新的。
  • 很高兴听到这个消息,@DaemonPainter。 PowerShell 通常是相当“自我意识”的——其他有用的命令是Get-CommandGet-Member——但帮助系统当然还有改进的余地。请注意,当您进入交互式 shell 时,PowerShell (Core) 7+ 现在提供引导提示:Type 'help' to get help. Running help 显示 PowerShell 帮助系统的高级概述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 2015-01-12
  • 2020-03-03
  • 2021-11-28
相关资源
最近更新 更多