Unix tail equivalent command in Windows Powershell

396,303

Solution 1

Use the -wait parameter with Get-Content, which displays lines as they are added to the file. This feature was present in PowerShell v1, but for some reason not documented well in v2.

Here is an example

Get-Content -Path "C:\scripts\test.txt" -Wait

Once you run this, update and save the file and you will see the changes on the console.

Solution 2

For completeness I'll mention that Powershell 3.0 now has a -Tail flag on Get-Content

Get-Content ./log.log -Tail 10

gets the last 10 lines of the file

Get-Content ./log.log -Wait -Tail 10

gets the last 10 lines of the file and waits for more

Also, for those *nix users, note that most systems alias cat to Get-Content, so this usually works

cat ./log.log -Tail 10

Solution 3

As of PowerShell version 3.0, the Get-Content cmdlet has a -Tail parameter that should help. See the technet library online help for Get-Content.

Solution 4

I used some of the answers given here but just a heads up that

Get-Content -Path Yourfile.log -Tail 30 -Wait 

will chew up memory after awhile. A colleague left such a "tail" up over the last day and it went up to 800 MB. I don't know if Unix tail behaves the same way (but I doubt it). So it's fine to use for short term applications, but be careful with it.

Solution 5

PowerShell Community Extensions (PSCX) provides the Get-FileTail cmdlet. It looks like a suitable solution for the task. Note: I did not try it with extremely large files but the description says it efficiently tails the contents and it is designed for large log files.

NAME
    Get-FileTail

SYNOPSIS
    PSCX Cmdlet: Tails the contents of a file - optionally waiting on new content.

SYNTAX
    Get-FileTail [-Path] <String[]> [-Count <Int32>] [-Encoding <EncodingParameter>] [-LineTerminator <String>] [-Wait] [<CommonParameters>]

    Get-FileTail [-LiteralPath] <String[]> [-Count <Int32>] [-Encoding <EncodingParameter>] [-LineTerminator <String>] [-Wait] [<CommonParameters>]

DESCRIPTION
    This implentation efficiently tails the cotents of a file by reading lines from the end rather then processing the entire file. This behavior is crucial for ef
    ficiently tailing large log files and large log files over a network.  You can also specify the Wait parameter to have the cmdlet wait and display new content
    as it is written to the file.  Use Ctrl+C to break out of the wait loop.  Note that if an encoding is not specified, the cmdlet will attempt to auto-detect the
     encoding by reading the first character from the file. If no character haven't been written to the file yet, the cmdlet will default to using Unicode encoding
    . You can override this behavior by explicitly specifying the encoding via the Encoding parameter.
Share:
396,303
mutelogan
Author by

mutelogan

Updated on January 06, 2022

Comments

  • mutelogan
    mutelogan over 2 years

    I have to look at the last few lines of a large file (typical size is 500MB-2GB). I am looking for a equivalent of Unix command tail for Windows Powershell. A few alternatives available on are,

    http://tailforwin32.sourceforge.net/

    and

    Get-Content [filename] | Select-Object -Last 10

    For me, it is not allowed to use the first alternative, and the second alternative is slow. Does anyone know of an efficient implementation of tail for PowerShell.

  • Rich
    Rich over 13 years
    Interesting. I would have thought that all arguments that exist also appear in help, yet man gc -par wait tells me there is no parameter. But I think this doesn't solve the problem that the OP has, since they asked for tail, not tail -f and an efficient implementation as well. Since this one also reads the complete file before returning the last lines this is painful for the file sizes they expect.
  • ravikanth
    ravikanth over 13 years
    Gotcha. May be IO.File has some way to seek to the required position. I will have to experiment a bit
  • Rich
    Rich over 13 years
    I guess one could implement it as a PowerShell function, using the normal .NET APIs. Seeking to the end, search backwards until the desired number of lines is found and emit them. Not pretty, probably, but might work. I just can't wrap my head around it right now, otherwise I would have started writing already ;-)
  • Keith Hill
    Keith Hill over 13 years
    There's a bug in the current version that is fixed in daily bits. I would recommend grabbing the latest bits and compiling them at least until we get an updated version released.
  • Keith Hill
    Keith Hill over 13 years
    FYI, this is what the Get-FileTail (alias tail) implementation does in PSCX. If you're curious you can look at the source code: pscx.codeplex.com/SourceControl/changeset/view/78514#1358075
  • mutelogan
    mutelogan over 13 years
    The solution "Get-Content -Path "C:\scripts\test.txt" -Wait" doesn't work well for large files as Joey commented. Thanks for all the suggestions.
  • JasonMArcher
    JasonMArcher over 13 years
    @Joey -Wait is a dynamic parameter that only applies to the FileSystem provider. GC can be used on any provider that implements that API. The only way besides documentation that I know to discover these is to use (gcm Get-Content).Parameters from within the appropriate provider path. Don't use the alias "gc" because the dynamic parameters will not show up.
  • Rich
    Rich over 13 years
    @Jason: Ah, damn it, I should have known. Yes, makes sense.
  • Jader Dias
    Jader Dias about 13 years
    The version 2.0 takes ages to show the 10 last lines of a 1GB csv file, and differently from Get-Content [filename] | Select-Object -Last 10 it can't be aborted
  • David Newcomb
    David Newcomb about 12 years
    I know it was a while ago, but this requires the process writing to the file to open, append, close it before Get-Content will work. If the writing process never closes the file then it won't work which is not the case with tail -f.
  • JoshL
    JoshL over 11 years
    Oddly, -Wait only shows me new lines when I access a log file in some way (such as selecting it in Windows Explorer). Tail provides updates as new lines are written to my file. With -Wait, I can leave a PowerShell window open happily showing no new lines while the file is being written to. If I then pop over and click on the file in Windows Explorer, suddenly PowerShell "wakes up" and catches up the remaining lines. Is this a bug?
  • Shagglez
    Shagglez over 11 years
    @JoshL - I noticed the same thing with Epilog, I guess it's using PowerShells under the bonnet.
  • Gedrox
    Gedrox over 11 years
  • tjmoore
    tjmoore over 11 years
    Note for some - PS 3.0 is Unavailable to Windows XP and Vista.
  • Abhishek
    Abhishek over 10 years
    @LauraLiparulo in what way does this not work? I've used it before definitely.
  • Coops
    Coops about 10 years
    I just used it and it worked spot on in this format Get-Content .\test.txt -Wait -Tail 1
  • Pecos Bill
    Pecos Bill over 9 years
    That's brutal on large files.
  • Govert
    Govert about 9 years
    Is it true that Get-Content with the -Tail option reads the entire file? On large files it seems OK for me.
  • hajamie
    hajamie about 9 years
    I believe it depends on the PS version. I've updated the answer. I was stuck on a server without the ability to install anything at the time, so the above code was useful.
  • yankee
    yankee about 9 years
    @JoshL: Indeed this does not work like tail -f. See: stackoverflow.com/questions/19919180/…
  • underscore_d
    underscore_d over 8 years
    Yeah, this is really not the same. Not only does it not handle persistently opened files as mentioned - it also has to print the entire file before it'll start showing you the changes - which is rather hopeless if you're trying to tail a log file 100s of MB in size.
  • elika kohen
    elika kohen almost 8 years
    @LauraLiparulo - Works for me also: Get-Content -Path .\sync.log -Wait -Tail 10
  • Robotnik
    Robotnik over 7 years
    @JoshL - View the folder in details mode in Explorer - when you click the file, watch the file size. It seems explorer doesn't really 'care' about refreshing the file until you click on it. Interesting that this is happening to PS as well, it must be lower-level than both Explorer and PS.
  • Tony Hinkle
    Tony Hinkle over 7 years
    Per the comment of JoshL above, I think this behavior is due to the application caching it's log writes and not flushing them to disk until the file is read. This is a common strategy for making logging more efficient. It certainly makes it a pain, though. You could perhaps work around it by having another script read (part?) of the file periodically...
  • Jake Nelson
    Jake Nelson over 7 years
    I use the technique mentioned by Dan but I record it in my $PROFILE. Open it with notepad $PROFILE. Then in the text document, create a new function: function Tail ($path) { Get-content -tail 15 -path $path -wait } This way you can access the function each time you start PowerShell.
  • Teoman shipahi
    Teoman shipahi about 7 years
    On ISE, I used to use while($true)/sleep and switched to this one, but this one also locks entire ISE and cannot run scripts on other tabs. Should I just start a new ISE instance?
  • Abhishek
    Abhishek about 7 years
    @Teomanshipahi In whwat way did the -Wait parameter not work for you?
  • Teoman shipahi
    Teoman shipahi about 7 years
    @GeorgeMauer conceptually I misunderstood how ISE works. I thought different tabs have their own context, but if one script runs on one tab, I cannot run other scripts on other tabs. I think this is expected behaviour.
  • Abdullah Leghari
    Abdullah Leghari about 7 years
    This should be the accepted answer. -Wait flag mentioned in currently accepted answer doesn't work anymore.
  • NoLifeKing
    NoLifeKing about 7 years
    My workaround was: while($true) { Clear-Host; Get-Content <filename> -tail 40; sleep 1 } :)
  • Robbie Dee
    Robbie Dee almost 7 years
    Great stuff - been trying to find a way to do this for ages. If I'm ever in Bangalore, I'll buy you a beer! :-D
  • nyagolova
    nyagolova over 6 years
    Sorry for silly question, but how do you exit the reading? How to tell the wait to stop waiting?
  • ravikanth
    ravikanth over 6 years
    CTRL+C should stop wait on the content.
  • Robear
    Robear about 6 years
    Powershell has an alias for cat, by default. So cat "C:\scripts\test.txt" -Wait would work as well, if you're accustom to the Unix syntax. You can also alter your powershell profile so you can just use the tail command: function tail { cat $args -Wait } will let you do tail "C:\scripts\test.txt". You can find the path to your profile in the $PROFILE variable.
  • Nico Nekoru
    Nico Nekoru almost 4 years
    Hello. Welcome to SO. Before you answer a question take notice of the 12 other answers, 3 having scores over 100.
  • Timo
    Timo over 3 years
    Can I tail a command, not a file? Such as history -tail 10?
  • Andries
    Andries over 3 years
    None of these have a follow options. Which is the 99% use case for using the tail command.
  • Jason S
    Jason S over 2 years
    @Andries did you see Ravikanth's answer? You can use -Wait to follow.
  • Admin
    Admin over 2 years
    Added the flag suggested by @JasonS