混合 Where-Object/ForEach-Object 语法
Posted
技术标签:
【中文标题】混合 Where-Object/ForEach-Object 语法【英文标题】:Hybrid Where-Object/ForEach-Object syntax 【发布时间】:2021-07-26 22:25:42 【问题描述】:我如何优雅地将Where-Object
与ForEach-Object
杂交?
Where-Object
cmdlet 有一种非常优雅的过滤对象的方式:
使用哪个语法:
... |Where-Object $_.Id -eq 2 | ...
现在可以写成:
... |Where-Object Id -eq 2 | ...
我正在寻找类似的 管道 条件语句,但不是过滤管道中的对象,而是更改相关对象在管道中并通过一切。像这样:
... |ForEach-Object if ($_.Id -eq 2) $_.Name = 'test' ; $_ | ...
换句话说,有没有办法用更少的括号、括号和当前对象($_
)引用来编写上述语法。就像在self-answer 中一样,但没有使用附加功能?
【问题讨论】:
【参考方案1】:使用MetaProgramming
模块,我能够在Where-Object
cmdlet 之上编写If-Object
cmdlet:
function If-Object
[CmdletBinding(DefaultParameterSetName='EqualSet', HelpUri='https://go.microsoft.com/fwlink/?LinkID=2096806', RemotingCapability='None')]
param(
[Parameter(ValueFromPipeline=$true)]
[psobject]
$InputObject,
[Parameter(ParameterSetName='ScriptBlockSet', Mandatory=$true, Position=0)]
[scriptblock]
$FilterScript,
[Parameter(ParameterSetName='Not', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveEqualSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='NotEqualSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveNotEqualSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='GreaterThanSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveGreaterThanSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='LessThanSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveLessThanSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='GreaterOrEqualSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveGreaterOrEqualSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='LessOrEqualSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveLessOrEqualSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='LikeSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveLikeSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='NotLikeSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveNotLikeSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='MatchSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveMatchSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='NotMatchSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveNotMatchSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='ContainsSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveContainsSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='NotContainsSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveNotContainsSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='InSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveInSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='NotInSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='CaseSensitiveNotInSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='IsSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='IsNotSet', Mandatory=$true, Position=0)]
[Parameter(ParameterSetName='EqualSet', Mandatory=$true, Position=0)]
[ValidateNotNullOrEmpty()]
[string]
$Property,
[Parameter(ParameterSetName='InSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveEqualSet', Position=1)]
[Parameter(ParameterSetName='NotEqualSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveNotEqualSet', Position=1)]
[Parameter(ParameterSetName='GreaterThanSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveGreaterThanSet', Position=1)]
[Parameter(ParameterSetName='LessThanSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveLessThanSet', Position=1)]
[Parameter(ParameterSetName='GreaterOrEqualSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveGreaterOrEqualSet', Position=1)]
[Parameter(ParameterSetName='LessOrEqualSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveLessOrEqualSet', Position=1)]
[Parameter(ParameterSetName='LikeSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveLikeSet', Position=1)]
[Parameter(ParameterSetName='NotLikeSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveNotLikeSet', Position=1)]
[Parameter(ParameterSetName='MatchSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveMatchSet', Position=1)]
[Parameter(ParameterSetName='NotMatchSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveNotMatchSet', Position=1)]
[Parameter(ParameterSetName='ContainsSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveContainsSet', Position=1)]
[Parameter(ParameterSetName='NotContainsSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveNotContainsSet', Position=1)]
[Parameter(ParameterSetName='EqualSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveInSet', Position=1)]
[Parameter(ParameterSetName='NotInSet', Position=1)]
[Parameter(ParameterSetName='CaseSensitiveNotInSet', Position=1)]
[Parameter(ParameterSetName='IsSet', Position=1)]
[Parameter(ParameterSetName='IsNotSet', Position=1)]
[System.Object]
$Value,
[Parameter(ParameterSetName='EqualSet')]
[Alias('IEQ')]
[switch]
$EQ,
[Parameter(ParameterSetName='CaseSensitiveEqualSet', Mandatory=$true)]
[switch]
$CEQ,
[Parameter(ParameterSetName='NotEqualSet', Mandatory=$true)]
[Alias('INE')]
[switch]
$NE,
[Parameter(ParameterSetName='CaseSensitiveNotEqualSet', Mandatory=$true)]
[switch]
$CNE,
[Parameter(ParameterSetName='GreaterThanSet', Mandatory=$true)]
[Alias('IGT')]
[switch]
$GT,
[Parameter(ParameterSetName='CaseSensitiveGreaterThanSet', Mandatory=$true)]
[switch]
$CGT,
[Parameter(ParameterSetName='LessThanSet', Mandatory=$true)]
[Alias('ILT')]
[switch]
$LT,
[Parameter(ParameterSetName='CaseSensitiveLessThanSet', Mandatory=$true)]
[switch]
$CLT,
[Parameter(ParameterSetName='GreaterOrEqualSet', Mandatory=$true)]
[Alias('IGE')]
[switch]
$GE,
[Parameter(ParameterSetName='CaseSensitiveGreaterOrEqualSet', Mandatory=$true)]
[switch]
$CGE,
[Parameter(ParameterSetName='LessOrEqualSet', Mandatory=$true)]
[Alias('ILE')]
[switch]
$LE,
[Parameter(ParameterSetName='CaseSensitiveLessOrEqualSet', Mandatory=$true)]
[switch]
$CLE,
[Parameter(ParameterSetName='LikeSet', Mandatory=$true)]
[Alias('ILike')]
[switch]
$Like,
[Parameter(ParameterSetName='CaseSensitiveLikeSet', Mandatory=$true)]
[switch]
$CLike,
[Parameter(ParameterSetName='NotLikeSet', Mandatory=$true)]
[Alias('INotLike')]
[switch]
$NotLike,
[Parameter(ParameterSetName='CaseSensitiveNotLikeSet', Mandatory=$true)]
[switch]
$CNotLike,
[Parameter(ParameterSetName='MatchSet', Mandatory=$true)]
[Alias('IMatch')]
[switch]
$Match,
[Parameter(ParameterSetName='CaseSensitiveMatchSet', Mandatory=$true)]
[switch]
$CMatch,
[Parameter(ParameterSetName='NotMatchSet', Mandatory=$true)]
[Alias('INotMatch')]
[switch]
$NotMatch,
[Parameter(ParameterSetName='CaseSensitiveNotMatchSet', Mandatory=$true)]
[switch]
$CNotMatch,
[Parameter(ParameterSetName='ContainsSet', Mandatory=$true)]
[Alias('IContains')]
[switch]
$Contains,
[Parameter(ParameterSetName='CaseSensitiveContainsSet', Mandatory=$true)]
[switch]
$CContains,
[Parameter(ParameterSetName='NotContainsSet', Mandatory=$true)]
[Alias('INotContains')]
[switch]
$NotContains,
[Parameter(ParameterSetName='CaseSensitiveNotContainsSet', Mandatory=$true)]
[switch]
$CNotContains,
[Parameter(ParameterSetName='InSet', Mandatory=$true)]
[Alias('IIn')]
[switch]
$In,
[Parameter(ParameterSetName='CaseSensitiveInSet', Mandatory=$true)]
[switch]
$CIn,
[Parameter(ParameterSetName='NotInSet', Mandatory=$true)]
[Alias('INotIn')]
[switch]
$NotIn,
[Parameter(ParameterSetName='CaseSensitiveNotInSet', Mandatory=$true)]
[switch]
$CNotIn,
[Parameter(ParameterSetName='IsSet', Mandatory=$true)]
[switch]
$Is,
[Parameter(ParameterSetName='IsNotSet', Mandatory=$true)]
[switch]
$IsNot,
[Parameter(ParameterSetName='Not', Mandatory=$true)]
[switch]
$Not,
[Parameter(ParameterSetName='Not', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveEqualSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='NotEqualSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveNotEqualSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='GreaterThanSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveGreaterThanSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='LessThanSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveLessThanSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='GreaterOrEqualSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveGreaterOrEqualSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='LessOrEqualSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveLessOrEqualSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='LikeSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveLikeSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='NotLikeSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveNotLikeSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='MatchSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveMatchSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='NotMatchSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveNotMatchSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='ContainsSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveContainsSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='NotContainsSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveNotContainsSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='InSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveInSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='NotInSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='CaseSensitiveNotInSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='IsSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='IsNotSet', Mandatory=$true, Position=2)]
[Parameter(ParameterSetName='EqualSet', Mandatory=$true, Position=2)]
[ValidateNotNullOrEmpty()]
$Process)
begin
try
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
$PSBoundParameters['OutBuffer'] = 1
[Void]$PSBoundParameters.Remove("Process")
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Core\Where-Object', [System.Management.Automation.CommandTypes]::Cmdlet)
catch
throw
process
try
if (& $wrappedCmd @PSBoundParameters)
if ($Process -is [ScriptBlock]) & $Process
else $_.$Property = $Process
$_
catch
throw
示例 1
$Test = @(
[PSCustomObject]@Id = 1; Name = 'One'
[PSCustomObject]@Id = 2; Name = 'Two'
[PSCustomObject]@Id = 3; Name = 'Three'
)
$Test |If-Object Id -eq 2 'test' |Format-Table
Id Name
-- ----
1 One
test Two
3 Three
示例 2
$Test = @(
[PSCustomObject]@Id = 1; Name = 'One'
[PSCustomObject]@Id = 2; Name = 'Two'
[PSCustomObject]@Id = 3; Name = 'Three'
)
$Test |If-Object Id -eq 2 $_.Name = 'test' |Format-Table
Id Name
-- ----
1 One
2 test
3 Three
【讨论】:
当您有两个条件或需要嵌套的ForEach
时会发生什么?我个人更喜欢问题中的“坏”示例,只是有一些换行符。或者更好的是,使用 Foreach ($item in $list) Do-Thing -to $item
而不是管道传输所有数据。以上是关于混合 Where-Object/ForEach-Object 语法的主要内容,如果未能解决你的问题,请参考以下文章
opencv4opencv视频教程 C++ 6图像混合线性混合混合权重相加addWeighted()混合加add()混合乘multiply()