【问题标题】:I cannot use begin/process/end block in a ForEach-Object?我不能在 ForEach-Object 中使用开始/处理/结束块?
【发布时间】:2015-09-11 15:39:12
【问题描述】:

我有以下代码:

function f()
{
    begin{$count=0}
    process{$count+=10}
    end{$count}
}
1..10|f # OK
1..10|%{
    begin{$count=0}
    process{$count+=10}
    end{$count}
} # Error

第一个“f”调用成功,而 %{} 块显示错误:

100
% : The script block cannot be invoked because it contains more than one clause. The Invoke() method can only be used on script blocks that contain a single clause.
At D:\Untitled1.ps1:13 char:7
+ 1..10|%{
+       ~~
    + CategoryInfo          : InvalidOperation: (:) [ForEach-Object], PSInvalidOperationException
    + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.ForEachObjectCommand

但是为什么呢? ForEach-Object 不支持 begin/process/end 块?

【问题讨论】:

  • ForEach-Object 采用参数 Begin、Process 和 End,它们都是脚本块,因此您不必编写函数 f 或包装器高级函数。 Process 参数的脚本块接受管道输入是没有意义的。使用其他参数。

标签: powershell foreach scriptblock


【解决方案1】:

ForEach-Object 将各个块作为单独的命名参数。

在你的情况下,那将是:

1..10 |ForEach-Object -Begin {$count=0} -Process {$count+=10} -End {$count}

这在帮助文件中有很好的记录 - 来自Get-Help ForEach-Object -Parameter *

-Begin <ScriptBlock>
    Specifies a script block that runs before processing any input objects.

    Required?                    false
    Position?                    named
    Default value                None
    Accept pipeline input?       false
    Accept wildcard characters?  false


-End <ScriptBlock>
    Specifies a script block that runs after processing all input objects.

    Required?                    false
    Position?                    named
    Default value                None
    Accept pipeline input?       false
    Accept wildcard characters?  false

<# ... #>

-Process <ScriptBlock[]>
    Specifies the operation that is performed on each input object. Enter a script
    block that describes the operation.

    Required?                    true
    Position?                    1
    Default value                None
    Accept pipeline input?       false
    Accept wildcard characters?  false

【讨论】:

    【解决方案2】:

    作为附录,如果您希望构建代码以便于阅读,请稍作补充。继续勾号(“`”)很重要——因为我刚刚发现自己要付出一些代价!

    Get-Content -Path $SelectedFiles | ForEach-Object `
    -Begin {
     #- Do Begin stuff -----
     } `
    -Process {
    #- Do Process stuff
    } `
    -End {
    #- Do End stuff
    }
    #- EndOf: ForEach is here -----
    #- NB! Continuation tick "`" must be preceded by space & be LAST character on line!!!!!
    

    为了在 ISE 中提供帮助,正确识别时,参数(Begin、Process、End)的颜色应该与其他参数(我的参数是黑色)相同。在 ISE 中使用上述代码,在勾号后放置一个空格,在勾号之前不要有空格等。 我没有意识到“空间”有多么重要——咧嘴一笑! 祝你好运!希望这对像我这样的初学者有所帮助。

    【讨论】:

      【解决方案3】:

      一个很酷的事情是,您可以在不指定参数的情况下执行此操作,并且它可以在幕后使用 -process 和 -remainingscripts。

      1..10 | ForEach {$count=0} {$count+=10} {$count}
      
      100
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-11
        • 1970-01-01
        • 2010-11-13
        • 2012-10-26
        相关资源
        最近更新 更多