Windows Powershell中的Unix尾部等效命令

时间:2010-12-13 06:55:28

标签: windows powershell tail

我必须查看大文件的最后几行(典型大小为500MB-2GB)。我正在寻找Windows Powershell的等效Unix命令tail。可用的一些替代方案是,

http://tailforwin32.sourceforge.net/

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

对我来说,不允许使用第一种选择,第二种选择是缓慢的。有没有人知道PowerShell的尾部有效实现。

13 个答案:

答案 0 :(得分:432)

-wait参数与Get-Content一起使用,该参数显示添加到文件中的行。此功能在PowerShell v1中出现,但由于某些原因在v2中没有很好地记录。

这是一个例子

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

运行此程序后,更新并保存文件,您将在控制台上看到更改。

答案 1 :(得分:153)

为了完整性,我会提到Powershell 3.0现在在Get-Content上有一个-Tail标志

Get-Content ./log.log -Tail 10

获取文件的最后10行

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

获取文件的最后10行并等待更多

此外,对于那些* nix用户,请注意大多数系统将 cat 别名为Get-Content,因此通常可以使用

cat ./log.log -Tail 10

答案 2 :(得分:113)

从PowerShell 3.0版开始,Get-Content cmdlet具有 -Tail 参数,应该有所帮助。见the technet library online help for Get-Content.

答案 3 :(得分:21)

我使用了这里给出的一些答案,但只是提醒

Get-Content -Path Yourfile.log -Tail 30 -Wait 
经过一段时间后,

会咀嚼记忆。一位同事离开了这样一个"尾巴"在最后一天,它上升到800 MB。我不知道Unix尾部的行为是否相同(但我对此表示怀疑)。因此,对短期应用程序使用它很好,但要小心它。

答案 4 :(得分:18)

PowerShell Community Extensions (PSCX)提供Get-FileTail cmdlet。它看起来像是一个适合该任务的解决方案。注意:我没有尝试使用非常大的文件,但描述说它有效地提供了内容,它是专为大型日志文件设计的。

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.

答案 5 :(得分:15)

只是对以前答案的一些补充。为Get-Content定义了别名,例如,如果您习惯于UNIX,则可能需要cat,还有typegc。而不是

Get-Content -Path <Path> -Wait -Tail 10

你可以写

# Print whole file and wait for appended lines and print them
cat <Path> -Wait
# Print last 10 lines and wait for appended lines and print them
cat <Path> -Tail 10 -Wait

答案 6 :(得分:3)

使用Powershell V2及以下版本,get-content会读取整个文件,因此对我没用。以下代码适用于我需要的内容,但字符编码可能存在一些问题。这实际上是tail -f,但是如果你想向后搜索换行符,可以很容易地修改它来获取最后的x个字节,或者最后的x行。

$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
}

我发现大部分代码都是here

答案 7 :(得分:3)

我使用@hajamie的解决方案并将其包装成稍微更方便的脚本包装器。

我添加了一个从文件末尾之前的偏移量开始的选项,因此您可以使用从文件末尾读取一定量的类似尾部的功能。请注意,偏移量以字节为单位,而不是行。

还可以选择继续等待更多内容。

示例(假设您将其保存为TailFile.ps1):

.\TailFile.ps1 -File .\path\to\myfile.log -InitialOffset 1000000
.\TailFile.ps1 -File .\path\to\myfile.log -InitialOffset 1000000 -Follow:$true
.\TailFile.ps1 -File .\path\to\myfile.log -Follow:$true

这是脚本本身......

param (
    [Parameter(Mandatory=$true,HelpMessage="Enter the path to a file to tail")][string]$File = "",
    [Parameter(Mandatory=$true,HelpMessage="Enter the number of bytes from the end of the file")][int]$InitialOffset = 10248,
    [Parameter(Mandatory=$false,HelpMessage="Continuing monitoring the file for new additions?")][boolean]$Follow = $false
)

$ci = get-childitem $File
$fullName = $ci.FullName

$reader = new-object System.IO.StreamReader(New-Object IO.FileStream($fullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [IO.FileShare]::ReadWrite))
#start at the end of the file
$lastMaxOffset = $reader.BaseStream.Length - $InitialOffset

while ($true)
{
    #if the file size has not changed, idle
    if ($reader.BaseStream.Length -ge $lastMaxOffset) {
        #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
    }

    if($Follow){
        Start-Sleep -m 100
    } else {
        break;
    }
}

答案 8 :(得分:2)

尝试Windows Server 2003 Resource Kit Tools

它包含一个tail.exe,可以在Windows系统上运行。

https://www.microsoft.com/en-us/download/details.aspx?id=17657

答案 9 :(得分:1)

非常基本,但在没有任何插件模块或PS版本要求的情况下完成所需的操作:

while ($true) {Clear-Host; gc E:\test.txt | select -last 3; sleep 2 }

答案 10 :(得分:1)

有很多有效的答案,但是没有一个与tail in linux相同语法。以下功能可以存储在您的$Home\Documents\PowerShell\Microsoft.PowerShell_profile.ps1中以保持持久性(有关更多详细信息,请参见powershell profiles documentation)。

这可以让您打电话...

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

非常接近linux语法。

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
    }
}

答案 11 :(得分:0)

对于回答者来说可能为时已晚,但是,尝试这个答案

Get-Content <filename> -tail <number of items wanted>

答案 12 :(得分:0)

可以从以下GitHub存储库下载为Windows编译的所有UNIX命令:https://github.com/George-Ogden/UNIX