【问题标题】:Hybrid Where-Object/ForEach-Object syntax混合 Where-Object/ForEach-Object 语法
【发布时间】: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 中一样,但没有使用附加功能?

【问题讨论】:

    标签: powershell if-statement foreach syntax where-clause


    【解决方案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 } 而不是管道传输所有数据。
    猜你喜欢
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2016-01-13
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    相关资源
    最近更新 更多