PowerShell equivalent for "head -n-3"?
Useful information is spread across other answers here, but I think it is useful to have a concise summary:
All lines except the first three
1..10 | Select-Object -skip 3returns (one per line): 4 5 6 7 8 9 10
All lines except the last three
1..10 | Select-Object -skip 3 -last 10returns (one per line): 1 2 3 4 5 6 7
That is, you can do it with built-in PowerShell commands, but there's that annoyance of having to specify the size going in. A simple workaround is to just use a constant larger than any possible input and you will not need to know the size a priori:
1..10 | Select-Object -skip 3 -last 10000000returns (one per line): 1 2 3 4 5 6 7
A cleaner syntax is to use, as Keith Hill suggested, the Skip-Object cmdlet from PowerShell Community Extensions (the Skip-Last function in Goyuix's answer performs equivalently but using PSCX saves you from having to maintain the code):
1..10 | Skip-Object -last 3returns (one per line): 1 2 3 4 5 6 7
First three lines
1..10 | Select-Object –first 3returns (one per line): 1 2 3
Last three lines
1..10 | Select-Object –last 3returns (one per line): 8 9 10
Middle four lines
(This works because the -skip
is processed before the -first
, regardless of the order of parameters in the invocation.)
1..10 | Select-Object -skip 3 -first 4returns (one per line): 4 5 6 7
Like the -First and -Last parameters, there is also a -Skip parameter that will help. It is worth noting that -Skip is 1 based, not zero.
# this will skip the first three lines of the text filecat myfile | select -skip 3
I am not sure PowerShell has something that gives you back everything except the last n lines pre-built. If you know the length you could just subtract n from the line count and use the -First parameter from select. You could also use a buffer that only passes lines through when it is filled.
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) }}
As a demo:
# this would display the entire file except the last five linescat myfile | Skip-Last -count 5
If you're using the PowerShell Community Extensions, there is a Take-Object cmdlet that will pass thru all output except the last N items e.g.:
30# 1..10 | Skip-Object -Last 4123456