Unix tail equivalent command in Windows Powershell

后端 未结 13 1567
攒了一身酷
攒了一身酷 2020-11-28 00:13

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 f

相关标签:
13条回答
  • 2020-11-28 00:47

    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.

    0 讨论(0)
  • 2020-11-28 00:47

    There have been many valid answers, however, none of them has the same syntax as tail in linux. The following function can be stored in your $Home\Documents\PowerShell\Microsoft.PowerShell_profile.ps1 for persistency (see powershell profiles documentation for more details).

    This allows you to call...

    tail server.log
    tail -n 5 server.log
    tail -f server.log
    tail -Follow -Lines 5 -Path server.log
    

    which comes quite close to the linux syntax.

    function tail {
    <#
        .SYNOPSIS
            Get the last n lines of a text file.
        .PARAMETER Follow
            output appended data as the file grows
        .PARAMETER Lines
            output the last N lines (default: 10)
        .PARAMETER Path
            path to the text file
        .INPUTS
            System.Int
            IO.FileInfo
        .OUTPUTS
            System.String
        .EXAMPLE
            PS> tail c:\server.log
        .EXAMPLE
            PS> tail -f -n 20 c:\server.log
    #>
        [CmdletBinding()]
        [OutputType('System.String')]
        Param(
            [Alias("f")]
            [parameter(Mandatory=$false)]
            [switch]$Follow,
    
            [Alias("n")]
            [parameter(Mandatory=$false)]
            [Int]$Lines = 10,
    
            [parameter(Mandatory=$true, Position=5)]
            [ValidateNotNullOrEmpty()]
            [IO.FileInfo]$Path
        )
        if ($Follow)
        {
            Get-Content -Path $Path -Tail $Lines -Wait
        }
        else
        {
            Get-Content -Path $Path -Tail $Lines
        }
    }
    
    0 讨论(0)
  • 2020-11-28 00:48

    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.

    0 讨论(0)
  • 2020-11-28 00:51

    It is possible to download all of the UNIX commands compiled for Windows from this GitHub repository: https://github.com/George-Ogden/UNIX

    0 讨论(0)
  • 2020-11-28 00:52

    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.

    0 讨论(0)
  • 2020-11-28 00:56

    Using Powershell V2 and below, get-content reads the entire file, so it was of no use to me. The following code works for what I needed, though there are likely some issues with character encodings. This is effectively tail -f, but it could be easily modified to get the last x bytes, or last x lines if you want to search backwards for line breaks.

    $filename = "\wherever\your\file\is.txt"
    $reader = new-object System.IO.StreamReader(New-Object IO.FileStream($filename, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [IO.FileShare]::ReadWrite))
    #start at the end of the file
    $lastMaxOffset = $reader.BaseStream.Length
    
    while ($true)
    {
        Start-Sleep -m 100
    
        #if the file size has not changed, idle
        if ($reader.BaseStream.Length -eq $lastMaxOffset) {
            continue;
        }
    
        #seek to the last max offset
        $reader.BaseStream.Seek($lastMaxOffset, [System.IO.SeekOrigin]::Begin) | out-null
    
        #read out of the file until the EOF
        $line = ""
        while (($line = $reader.ReadLine()) -ne $null) {
            write-output $line
        }
    
        #update the last max offset
        $lastMaxOffset = $reader.BaseStream.Position
    }
    

    I found most of the code to do this here.

    0 讨论(0)
提交回复
热议问题