Get-Content -Head and -Tail should behave like head and tail with negative parameters
See original GitHub issuePrerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest released version
- Search the existing issues.
- Refer to the FAQ.
- Refer to Differences between Windows PowerShell 5.1 and PowerShell.
Steps to reproduce
SYSTEMATIC REVIEW by @mklement0
Get-Content -Head and -Tail should behave like head and tail with negative parameters, I checked the code and this is by design but I think its not the corect behaviour.
https://www.gnu.org/software/coreutils/manual/html_node/head-invocation.html https://www.gnu.org/software/coreutils/manual/html_node/tail-invocation.html
Create txt file:
@"
1
2
3
4
5
6
"@ | Set-Content file.txt
Expected behavior
Get-Content file.txt -Head -3
head file.txt -n-3
4
5
6
Get-Content file.txt -Tail -3
tail file.txt -n-3
1
2
3
Actual behavior
Get-Content file.txt -Head -3
Get-Content file.txt -Tail -3
1
2
3
4
5
6
Error details
No response
Environment data
Name Value
---- -----
PSVersion 7.3.4
PSEdition Core
GitCommitId 7.3.4
OS Microsoft Windows 10.0.19045
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Visuals
No response
Issue Analytics
- State:
- Created 4 months ago
- Reactions:1
- Comments:9 (4 by maintainers)
Top Results From Across the Web
Negative arguments to head / tail - shell script
Some implementations of head like GNU head support: head -n -12. but that's not standard. tail -r file | tail -n +13 |...
Read more >Get last n lines or bytes of a huge file in Windows (like ...
If you have PowerShell 3 or higher, you can use the -Tail parameter for Get-Content to get the last n lines. Get-content -tail...
Read more >Get-Content (Microsoft.PowerShell.Management)
Specifies the number of lines from the end of a file or other item. You can use the Tail parameter name or its...
Read more >The head and tail commands in Linux
Both the head and the tail commands are members of the GNU coreutils package. They are, by default, installed in all Linux distributions....
Read more >Opposite of tail: all lines except the last n lines
to print all but the last 5 lines of file.txt . If head -n takes no negative arguments, try head -n $(( $(wc...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Here’s a systematic overview of what the
head
andtail
do with negative numbers and whattail -n +$n
does (explicit+
prefix), along with the equivalent PowerShell commands:Note that in the syntax form
head -5
andtail -5
the-
doesn’t actually indicate a negative number, but is the option ID char - syntactic sugar that is a shortcut tohead -n 5
andtail -n 5
(head --lines=5
andtail --lines=5
).One possible resolution:
head
andtail
, introduce-Skip
and-SkipLast
parameters toGet-Content
-First
and-Last
parameters: in this case it isn’t just about convenience and concision, but also about performance.At the moment
head -5
or Or-First -5
return the whole file The problem is negative values are ignored .Select-object
gives an error if-index
-first
or-last
is negative. ArguablyGC "foo.txt" -first $x
andGc "foo.txt | select -first $x
should do the same for all values of $x. So EITHER Get-Content should validate the parameters and reject negative values OR both should be updated to process negative numbersWhen I just tried
head -5
is treated ashead 5
buthead -n -5
gives lines 0 to length -5.however
tail -5
andtail -n -5
both return the last 5 lines.(in other words you can get first n lines, last n lines, and all but the last n lines, but not all but the first n)
So a user might reasonably expect any of:
select-object
-head x
/-first x
and-tail x
/last x
work with (abs(x) ) -like thehead
command without-n
and thetail
command with or without-n
-head -n
/first -n
is read as (length - n )" -like thehead
command with-n
and-last
/-tail
does the same - which is different from the tail command.-First
/-Head
doing (length -n) for negatives and-Last
/-Tail
doing abs().-first -n
is actually-last +n
(and vice versa) -like(gc ...)[-1..-n]
but unlikehead
andtail
commands.The first two give consistent behaviour. The last two are horrible and really just for completeness.
Whether making
-Tail
work likehead -n
and not liketail
/tail -n
is something people will doubtless argue over. I think modifying GC so it can easily get the first n, or remove the first n, get the last n or remove last n. is functionally better despite that. Technically it’s a breaking change but it’s unlikely anyone relies on current behaviour, bringing the same thing to Select-Object would also be useful but is a slightly worse breaking change (with$files | select -first $n | del
if an error says $n is -1, nothing is selected, but ifselect-object
treats -1 as ‘all but the last 1’ lots gets deleted).I think the cmdlets wg should have a look at this and I’ll try to get in on the agenda.