Home > Software engineering >  Powershell subsettimg square brackets NOT condition
Powershell subsettimg square brackets NOT condition

Time:10-30

I have this array as shown here

$files=1..10

I want to return everything except for the 4th object

Is there a simpler way instead of this? This works but I think there has to be a easier way.

$files[0,1,2,4,5,6,7,8,9]

CodePudding user response:

In PowerShell Core the easiest solution is to use Select-Object -SkipIndex i.e.:

$files = 1..10
$files | Select-Object -SkipIndex 1, 2, 4

3
5
6
7
8
9
10

Otherwise, if you want to do it via indexing the solution is more cumbersome:

# if you want to do it dynamically (not hardcoding the index of the last element)
$files[0..2   4..($files.Length - 1)]

If you don't want to or can't install the latest version of PowerShell and still would like to have the same -SkipIndex functionality as demonstrated above, you could have your own wrapper around Select-Object with a SteppablePipeline and store the wrapper in your $PROFILE so it gets loaded every time you start a new session. Note that this code is autogenerated using the ProxyCommand Class and the only added logic to it is:

  • In begin block:
if($withSkipIndex = $PSBoundParameters.Remove('SkipIndex')) {
    $i = 1
}
  • In process block:
if($withSkipIndex -and $i   -in $SkipIndex) {
    return
}

Wrapper Code:

function Select-Object2 {
    [CmdletBinding(
        DefaultParameterSetName='DefaultParameter',
        HelpUri='https://go.microsoft.com/fwlink/?LinkID=2096716',
        RemotingCapability='None'
    )]
    param(
        [Parameter(ValueFromPipeline=$true)]
        [psobject]
        ${InputObject},

        [Parameter(ParameterSetName='DefaultParameter', Position=0)]
        [Parameter(ParameterSetName='SkipLastParameter', Position=0)]
        [System.Object[]]
        ${Property},

        [Parameter(ParameterSetName='DefaultParameter')]
        [Parameter(ParameterSetName='SkipLastParameter')]
        [string[]]
        ${ExcludeProperty},

        [Parameter(ParameterSetName='DefaultParameter')]
        [Parameter(ParameterSetName='SkipLastParameter')]
        [string]
        ${ExpandProperty},

        [switch]
        ${Unique},

        [Parameter(ParameterSetName='DefaultParameter')]
        [ValidateRange(0, 2147483647)]
        [int]
        ${Last},

        [Parameter(ParameterSetName='DefaultParameter')]
        [ValidateRange(0, 2147483647)]
        [int]
        ${First},

        [Parameter(ParameterSetName='DefaultParameter')]
        [ValidateRange(0, 2147483647)]
        [int]
        ${Skip},

        [Parameter(ParameterSetName='SkipLastParameter')]
        [ValidateRange(0, 2147483647)]
        [int]
        ${SkipLast},

        [Parameter(ParameterSetName='DefaultParameter')]
        [Parameter(ParameterSetName='IndexParameter')]
        [switch]
        ${Wait},

        [Parameter(ParameterSetName='IndexParameter')]
        [ValidateRange(0, 2147483647)]
        [int[]]
        ${Index},

        [Parameter(ParameterSetName='SkipIndexParameter')]
        [ValidateRange(0, 2147483647)]
        [int[]]
        ${SkipIndex}
    )

    begin {
        $outBuffer = $null
        if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
            $PSBoundParameters['OutBuffer'] = 1
        }

        if($withSkipIndex = $PSBoundParameters.Remove('SkipIndex')) {
            $i = 1
        }

        $wrappedCmd = Get-Command 'Microsoft.PowerShell.Utility\Select-Object'
        $scriptCmd  = { & $wrappedCmd @PSBoundParameters }

        $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
        $steppablePipeline.Begin($PSCmdlet)
    }

    process {
        if($withSkipIndex -and $i   -in $SkipIndex) {
            return
        }
        $steppablePipeline.Process($_)
    }
    end {
        $steppablePipeline.End()
    }
}

Usage is exactly the same as Select-Object:

$files | Select-Object2 -SkipIndex 1, 2, 4

3
5
6
7
8
9
10
  • Related