“的等效PowerShell;总目-n-3“;?

“的等效PowerShell;总目-n-3“;?,powershell,tail,unix-head,Powershell,Tail,Unix Head,我已经能够追踪到基本的头部/尾部功能: head -10 myfile <==> cat myfile | select -first 10 tail -10 myfile <==> cat myfile | select -last 10 head-10 myfile cat myfile |选择-first 10 尾部-10 myfile类别myfile |选择-last 10 但是如果我想列出除最后三行之外的所有行或者除前三行之外的所有行,你怎么做?在Unix中

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

head -10 myfile <==> cat myfile | select -first 10
tail -10 myfile <==> cat myfile | select -last 10
head-10 myfile cat myfile |选择-first 10
尾部-10 myfile类别myfile |选择-last 10

但是如果我想列出除最后三行之外的所有行或者除前三行之外的所有行,你怎么做?在Unix中,我可以执行“head-n-3”或“tail-n+4”。对于PowerShell,如何实现这一点并不明显。

除了第一个
n
之外,其他所有功能都可以使用

... | Select -skip $n
... | select -skiplast $n

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

您可以这样做:

[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

与-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
如果您正在使用,则存在一个Take Object cmdlet,该cmdlet将传递除最后N项之外的所有输出,例如:

30# 1..10 | Skip-Object -Last 4
1
2
3
4
5
6

有用的信息分布在这里的其他答案中,但我认为有一个简明的摘要是有用的:

除前三行以外的所有行

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
除最后三行之外的所有行

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 | Select-Object –first 3
returns (one per line): 1 2 3
1..10 | Select-Object –last 3
returns (one per line): 8 9 10
最后三行

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
中间四行

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
之前处理的。)


除了最后一个
n
外,所有操作都可以用

... | Select -skip $n
... | select -skiplast $n