混合 Where-Object/ForEach-Object 语法

Posted

技术标签:

【中文标题】混合 Where-Object/ForEach-Object 语法【英文标题】:Hybrid Where-Object/ForEach-Object syntax 【发布时间】:2021-07-26 22:25:42 【问题描述】:

我如何优雅地将Where-ObjectForEach-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()

高斯混合模型GMM核心参数高斯混合模型GMM的数学形式

OpenGL颜色混合原理

Sass混合的使用

带有 Alpha 混合控件的 C# Alpha 混合表单

如何从混合任务中运行混合任务?