Manu's helpful ... | Select-Object -Skip 1 | Select-Object -SkipLast 1
solution在PSv5 +的伟大工程(假设第一和最后一行应该是从消除输出)。
然而,他们的PSv4-解决方案不起作用(本文写作时),因为Get-Content $file | Select-Object -Skip 1
返回的数组([System.Object[]]
实例)没有一个.GetRange()
方法。
下面是一个使用PowerShell的范围操作符(..
)一个有效的解决方案:
# Read lines of the input file into an array.
$allLines = Get-Content $file
# Using the range operator (..), get all elements except the first and the last.
$allLines[1..([Math]::Max(1, $allLines.Count-2))]
注:
*试图[1..-1]
是诱人的,但确实在PowerShell中不的工作,因为1..-1
计算结果为标1, 0, -1
。
*如果您知道至少有输入对象,则可以省略[Math]::Max()
电话。
上述解决方案,但是,不总是一种选择,因为它需要收集所有输入对象在存储器第一,其否定存储器节流,一个接一个的处理,一个管道为基础的解决方案提供。
(虽然内存解决方案,如果可行的话,是更快)
为了解决在PSv4-,您可以在管道友好方式效仿Select-Object -SkipLast 1
如下(Select-Object -Skip 1
- 跳过开始-是在PSv4-中支持)。
# 'one', 'two', 'three' is a sample array. Output is 'one', 'two'
'one', 'two', 'three' | ForEach-Object { $notFirst = $False } {
if ($notFirst) { $prevObj }; $prevObj = $_; $notFirst = $True
}
每个输入对象的输出被延迟一次迭代,这有效地省略了最后一次。
这里的泛化-SkipLast <n>
,如先进的功能Skip-Last
,它使用一个[System.Collections.Generic.Queue[]]
例如通过<n>
对象延迟输出实现:
# Works in PSv2+
Function Skip-Last {
<#
.SYNOPSIS
Skips the last N input objects provided via the pipeline.
Default for N is 1.
#>
[CmdletBinding()]
param(
[ValidateRange(1, 2147483647)] [int] $Count = 1,
[Parameter(Mandatory=$True, ValueFromPipeline=$True)]$InputObject
)
begin {
if (-not $MyInvocation.ExpectingInput) { }
$qeuedObjs = New-Object System.Collections.Generic.Queue[object] $Count
}
process {
if ($qeuedObjs.Count -eq $Count) {
$qeuedObjs.Dequeue()
}
$qeuedObjs.Enqueue($InputObject)
}
}
注:在上面的ValidateRange()
属性,2147483647
来代替,因为在这种情况下PSv2仅支持常量。
样品电话:
PS> 'one', 'two', 'three', 'four', 'five' | Skip-Last 3
one
two
难道要删除的第一个和最后一行或让他们保持不变? – LotPings