我必须查看大文件的最后几行(通常大小为500MB-2GB)。我正在寻找tail
Windows Powershell 的等效Unix命令。有几种可用的替代方法,
http://tailforwin32.sourceforge.net/
和
获取内容[文件名] | 选择对象-最后10个
对我来说,不允许使用第一种选择,第二种选择很慢。有谁知道PowerShell的tail的高效实现。
Get-Content [filename] -last 10
并添加-tail
-f
我必须查看大文件的最后几行(通常大小为500MB-2GB)。我正在寻找tail
Windows Powershell 的等效Unix命令。有几种可用的替代方法,
http://tailforwin32.sourceforge.net/
和
获取内容[文件名] | 选择对象-最后10个
对我来说,不允许使用第一种选择,第二种选择很慢。有谁知道PowerShell的tail的高效实现。
Get-Content [filename] -last 10
并添加-tail
-f
Answers:
将-wait
参数与Get-Content一起使用,在将行添加到文件中时会显示该行。PowerShell v1中存在此功能,但是由于某些原因,v2中没有对此文档进行很好的记录。
这是一个例子
Get-Content -Path "C:\scripts\test.txt" -Wait
运行此命令后,更新并保存文件,您将在控制台上看到更改。
man gc -par wait
告诉我没有参数。但是我认为这并不能解决OP所存在的问题,因为他们要求的tail
不是tail -f
有效的实现。由于此文件在返回最后几行之前还读取了完整的文件,因此对于他们期望的文件大小来说很痛苦。
为了完整起见,我将提到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
Get-Content .\test.txt -Wait -Tail 1
Get-Content -Path .\sync.log -Wait -Tail 10
-Wait
参数不适用于您吗?
从PowerShell版本3.0开始,Get-Content cmdlet具有应提供帮助的-Tail参数。请参阅Technet库在线帮助以获取内容。
PowerShell社区扩展(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.
Get-Content [filename] | Select-Object -Last 10
它不能被中止的方式不同
只是先前答案的一些补充。有为Get-Content定义的别名,例如,如果您习惯使用UNIX,则可能cat
还有type
和gc
。所以代替
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
使用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
}
我在这里找到了大多数代码来执行此操作。
我采用了@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;
}
}
尝试 Windows Server 2003 Resource Kit Tools
它包含一个 tail.exe
可以在Windows系统上运行的。
https://www.microsoft.com/zh-cn/download/details.aspx?id=17657
非常基本,但是不需要任何附加模块或PS版本要求就可以满足您的需求:
while ($true) {Clear-Host; gc E:\test.txt | select -last 3; sleep 2 }
while($true) { Clear-Host; Get-Content <filename> -tail 40; sleep 1 }
:)
有很多有效的答案,但是,没有一个与linux中tail的语法相同。可以将以下功能存储在您的设备中以保持持久性(请参阅Powershell配置文件文档)$Home\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
有关更多详细信息,)。
这使您可以致电...
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
}
}