21

我已经能够追踪基本的头/尾功能:

head -10 myfile <==> cat myfile | select -first 10
tail -10 myfile <==> cat myfile | select -last 10

但是,如果我想列出除最后三行之外的所有行或除前三行之外的所有行,你该怎么做?在 Unix 中,我可以执行“head -n-3”或“tail -n+4”。如何为 PowerShell 完成此操作并不明显。

4

6 回答 6

21

有用的信息分布在此处的其他答案中,但我认为有一个简洁的摘要很有用:

除前三行外的所有

1..10 | Select-Object -skip 3
returns (one per line): 4 5 6 7 8 9 10

除了最后三行之外的所有行

1..10 | Select-Object -skip 3 -last 10
returns (one per line): 1 2 3 4 5 6 7

也就是说,您可以使用内置的 PowerShell 命令来执行此操作,但是必须指定输入的大小很烦人。一个简单的解决方法是使用比任何可能的输入都大的常量,您不需要知道大小先验:

1..10 | Select-Object -skip 3 -last 10000000
returns (one per line): 1 2 3 4 5 6 7

正如 Keith Hill 建议的那样,更简洁的语法是使用 PowerShell Community Extensions 中的 Skip-Object cmdlet(Goyuix 的答案中的 Skip-Last 函数执行相同,但使用 PSCX 可以使您不必维护代码):

1..10 | Skip-Object -last 3
returns (one per line): 1 2 3 4 5 6 7

前三

1..10 | Select-Object –first 3
returns (one per line): 1 2 3

最后三行

1..10 | Select-Object –last 3
returns (one per line): 8 9 10

中间四行

(这是有效的,因为无论调用中参数的顺序如何,都是-skip在 之前处理的。)-first

1..10 | Select-Object -skip 3 -first 4
returns (one per line): 4 5 6 7
于 2012-04-11T20:30:36.917 回答
9

与 -First 和 -Last 参数一样,还有一个 -Skip 参数会有所帮助。值得注意的是,-Skip 是从 1 开始的,而不是从零开始的。

# this will skip the first three lines of the text file
cat myfile | select -skip 3

我不确定 PowerShell 是否有什么东西可以让你返回除了最后 n 行预构建的所有内容。如果您知道长度,您可以从行数中减去 n 并使用 select 中的 -First 参数。您还可以使用仅在填充时通过行的缓冲区。

function Skip-Last {
  param (
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)][PsObject]$InputObject,
    [Parameter(Mandatory=$true)][int]$Count
  )

  begin {
    $buf = New-Object 'System.Collections.Generic.Queue[string]'
  }

  process {
    if ($buf.Count -eq $Count) { $buf.Dequeue() }
    $buf.Enqueue($InputObject)
  }
}

作为演示:

# this would display the entire file except the last five lines
cat myfile | Skip-Last -count 5
于 2012-04-09T22:14:40.880 回答
2

如果您使用的是PowerShell Community Extensions,则有一个 Take-Object cmdlet 将传递除最后 N 项之外的所有输出,例如:

30# 1..10 | Skip-Object -Last 4
1
2
3
4
5
6
于 2012-04-09T22:37:47.647 回答
1

你可以这样做:

[array]$Service = Get-Service
$Service[0] #First Item
$Service[0..2] #First 3 Items
$Service[3..($Service.Count)] #Skip the first 3 lines
$Service[-1] #Last Item
$Service[-3..-1] #Last 3 Items
$Service[0..($Service.Count -4)] #Skip the last 3 lines
于 2012-04-09T22:13:59.383 回答
1

除了最后一个之外,所有的n都可以用

... | select -skiplast $n
于 2017-11-09T19:22:39.103 回答
0

除了第一个之外,所有的n都可以用

... | Select -skip $n

然而,所有“除了最后一个m”都没有内置任何内容。将整个输入加载到一个数组中以获得长度是可行的——当然对于可能对内存提出不合理要求的大输入。

于 2012-04-09T21:58:47.130 回答