Windows Powershell中的Unix tail等效命令

我必须看一个大文件的最后几行(典型的大小是500MB-2GB)。 我正在寻找相当于Windows Powershell的Unix命令tail 。 有几个可供select的是,

http://tailforwin32.sourceforge.net/

  Get-Content [文件名] | select对象 - 最多10 

对我来说,不允许使用第一种select,第二种select是慢的。 有谁知道有效的PowerShell尾部实施。

在Get-Content中使用-wait参数,在添加到文件时显示行。 此function出现在PowerShell v1中,但出于某种原因在v2中没有很好的logging。

这是一个例子

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

一旦你运行这个,更新并保存文件,你会看到在控制台上的变化。

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

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

 Get-Content ./log.log -Tail 10 

获取文件的最后10行

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

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

PowerShell社区扩展(PSCX)提供了Get-FileTail cmdlet 。 它看起来像是一个合适的解决scheme。 注意:我没有尝试使用非常大的文件,但描述表明它有效地拖尾了内容,它是为大型日志文件而devise的。

 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. 

我使用了一些在这里给出的答案,但只是提出了一个问题

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

会在一段时间后咀嚼记忆。 一位同事在最后一天离开了这样一个“尾巴”,并升到了800 MB。 我不知道Unix尾巴的行为是否一样(但我怀疑它)。 所以短期应用可以使用,但要小心。

只是以前的答案一些补充。 为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 

我采取了@ hajamie的解决scheme,并将其包装成稍微更方便的脚本包装。

我添加了一个选项,在文件结束之前从一个偏移量开始,所以你可以使用从文件末尾读取一定数量的尾巴式function。 请注意偏移量以字节为单位,而不是行。

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

示例(假设您保存为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; } } 

使用Powershell V2及以下版本,get-content会读取整个文件,所以对我来说没用。 下面的代码适用于我所需要的,尽pipe字符编码可能存在一些问题。 这实际上是尾巴-f,但它可以很容易地修改得到最后x个字节,或者如果你想向后search换行符,最后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 } 

我发现大部分代码都是在这里完成的 。

非常基本的,但没有任何附加模块或PS版本的要求,你需要什么:

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