我管道单个字符串并使用For-EachObject
处理它,如下所示:
"Test" | % { $_.Substring(0,1) }
使用For-EachObject
处理单个管道项目似乎是错误的,部分原因是它会对未来的代码维护者产生误导。但是,我不知道任何其他方式来捕捉字符串,同时说“它只是一个单项”。例如,这不起作用。
"Test" | $_.Substring(0,1)
"Test" | { $_.Substring(0,1) }
如何处理单个对象,同时表明我只期望一个?
以上是我实际想要完成的简化版本。我得到了维基百科文章的第一段,它是a larger function that saves the result to a file的一部分。
curl "www.wikipedia.org/wiki/Hope,_British_Columbia" |
select -expand allelements |
? { $_.id -eq "mw-content-text" } |
select -expand innerHTML |
% {
$i = $_.IndexOf("<P>");
$j = $_.IndexOf("</P>");
$_.Substring($i, $j - $i) -replace '<[^>]*>'
}
需要处理单个对象的部分遵循select -expand innerHtml
表达式。管道是我的首选方式,因为在curl
部分周围放置多个括号似乎很难看。
curl
是Invoke-WebRequest
select
是Select-Object
-expand
是ExplandProperty
?
是Where-Object
%
是For-EachObject
答案 0 :(得分:5)
如果您正在创建控制输入和输出的单一用途代码,并且始终只有一个对象,那么使用管道是过度的而不是真的合适。只需将字符串作为参数传递给您的函数。
function f([String]$s) {
$s.Substring(0,1)
}
PS> f "Test" T
如果要构建通用函数以从管道获取输入,则您的函数需要考虑流中的多个对象。幸运的是,PowerShell使用Process{}
块有一种自然的方法,它对输入管道中的每个项执行一次。
function f {
param(
[Parameter(ValueFromPipeline=$true)]
[String]$item
)
process {
$item.Substring(0,1)
}
}
PS> '123','abc','#%@' | f 1 a #
这是一个很常见的函数,PowerShell有一个简写来编写一个函数,该函数从管道中获取一个参数并且只包含一个进程块。
filter f {
$_.SubString(0,1)
}
PS> '123','abc','#%@' | f 1 a #