我正在查看PowerShell的Rename-Item
cmdlet的文档,并且有一个这样的示例。
Get-ChildItem *.txt | Rename-Item -NewName { $_.name -Replace '\.txt','.log' }
注意最后一句话:
NewName的值是一个脚本块,在将值提交给NewName参数之前运行。
实际上
NewName
是一个字符串:[-NewName] <String>
那么这是否意味着当所需的参数类型为字符串时,我总是可以使用脚本块吗? 最佳答案
# Delay-bind script-block argument:
# The code inside { ... } is executed for each input object ($_) and
# the output is passed to the -NewName parameter.
... | Rename-Item -NewName { $_.Name -replace '\.txt$','.log' }
上面的调用显示了延迟绑定(bind)脚本块({ ... }
)参数的应用,该参数是隐式功能,它具有:的
[scriptblock]
[object]
(但是[psobject]
确实起作用,因此也适用[pscustomobject]
)[object]
ValueFromPipelineBy
)或按属性名(ValueFromPipelineByPropertyName
)接受管道输入都是无关紧要的。$_
在脚本块内部进行访问,并且脚本块的输出(假定为参数的类型正确)用作参数。ValueFromPipelineByPropertyName
并且该对象缺少该名称的属性也是如此。Rename-Item
的调用之类的技术,其中Get-Item
的管道输入(通常)绑定(bind)到-LiteralPath
参数,但是将脚本块传递给-NewName
-通常只绑定(bind)到具有.NewName
属性的输入对象-启用对同一管道对象的访问,从而从输入文件名派生目标文件名:Get-Item file | Rename-Item -NewName { $_.Name + '1' } # renames 'file' to 'file1'
;输入同时绑定(bind)到-LiteralPath
和-NewName
脚本块。 ForEach-Object
或Where-Object
的脚本块不同, delay-bind脚本块在子变量范围 [2]中运行,这意味着您无法直接修改调用者的变量,例如在输入中增加计数器对象。解决方法是,使用在调用方作用域中声明的
[ref]
类型的变量,并在脚本块中访问其.Value
属性-有关示例,请参见this answer。[1]错误条件:
[scriptblock]
-或[object]
类型(无类型)的参数,则会发生常规参数绑定(bind):即,脚本块作为(可能是转换的)值传递,并且不进行评估。
[object]
或[scriptblock]
类型的参数/可转换为脚本块的委托(delegate)类型(例如System.Func
),脚本块将按原样绑定(bind)。 [string]
类型的参数,脚本块的文字内容作为字符串值传递。 Cannot evaluate parameter '<name>' because its argument is specified as a script block and there is no input. A script block cannot be evaluated without input.
[2]这个差异正在this GitHub issue中讨论。
关于powershell - 对于PowerShell cmdlet,是否可以始终将脚本块传递给字符串参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52805820/