Windows Powershell 中的 Unix tail 等效命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4426442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:52:10  来源:igfitidea点击:

Unix tail equivalent command in Windows Powershell

windowspowershelltail

提问by mutelogan

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 tailfor Windows Powershell. A few alternatives available on are,

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

http://tailforwin32.sourceforge.net/

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.

对我来说,不允许使用第一种选择,第二种选择很慢。有谁知道 PowerShell 的 tail 的有效实现。

回答by ravikanth

Use the -waitparameter 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.

将该-wait参数与 Get-Content 一起使用,它会在行添加到文件时显示行。此功能存在于 PowerShell v1 中,但由于某种原因在 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.

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

回答by George Mauer

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

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

Get-Content ./log.log -Tail 10

gets the last 10 lines of the file

获取文件的最后 10 行

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

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

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

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

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

cat ./log.log -Tail 10

回答by Dan Blanchard

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

从 PowerShell 3.0 版开始,Get-Content cmdlet 有一个-Tail参数应该会有所帮助。有关Get-Content,请参阅technet 库联机帮助。

回答by John Lockwood

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.

一段时间后会咀嚼记忆。一位同事在最后一天留下了这样一个“尾巴”,它达到了 800 MB。我不知道 Unix tail 的行为是否相同(但我对此表示怀疑)。所以它可以用于短期应用,但要小心。

回答by Roman Kuzmin

PowerShell Community Extensions (PSCX)provides the Get-FileTailcmdlet. 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.

PowerShell 社区扩展 (PSCX)提供了Get-FileTailcmdlet。它看起来是适合该任务的解决方案。注意:我没有对超大文件进行尝试,但描述说它有效地跟踪内容并且它是为大日志文件设计的。

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.

回答by Mikael Sundberg

Just some additions to previous answers. There are aliases defined for Get-Content, for example if you are used to UNIX you might like cat, and there are also typeand gc. So instead of

只是对先前答案的一些补充。为 Get-Content 定义了别名,例如,如果您习惯于 UNIX,您可能会喜欢cat,还有typegc。所以代替

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

you can write

你可以写

# 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

回答by Brian Reischl

I took @hajamie's solution and wrapped it up into a slightly more convenient script wrapper.

我采用了@hajamie 的解决方案并将其包装成一个稍微方便的脚本包装器。

I added an option to start from an offset before the end of the file, so you can use the tail-like functionality of reading a certain amount from the end of the file. Note the offset is in bytes, not lines.

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

There's also an option to continue waiting for more content.

还有一个选项可以继续等待更多内容。

Examples (assuming you save this as TailFile.ps1):

示例(假设您将其另存为 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

And here is the script itself...

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

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

回答by hajamie

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.

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

I found most of the code to do this here.

我在这里找到了执行此操作的大部分代码。

回答by starshine wang

try Windows Server 2003 Resource Kit Tools

尝试 Windows Server 2003 Resource Kit Tools

it contains a tail.exewhich can be run on Windows system.

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

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

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

回答by EvosDeMercile

Probably too late for an answere but, try this one

可能为时已晚,但是,试试这个

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