tail
。有几个可用的替代方案,包括:
http://tailforwin32.sourceforge.net/
和
Get-Content [filename] | Select-Object -Last 10对于我来说,不允许使用第一个替代方案,而第二个替代方案速度较慢。是否有人知道适用于PowerShell的高效实现tail的方法?
tail
。有几个可用的替代方案,包括:
http://tailforwin32.sourceforge.net/
和
Get-Content [filename] | Select-Object -Last 10对于我来说,不允许使用第一个替代方案,而第二个替代方案速度较慢。是否有人知道适用于PowerShell的高效实现tail的方法?
使用-wait
参数与Get-Content一起使用,它会显示添加到文件中的行。这个功能在PowerShell v1中就已经存在了,但是在v2中由于某些原因没有很好地记录。
下面是一个示例:
Get-Content -Path "C:\scripts\test.txt" -Wait
运行此代码后,更新并保存文件,您将在控制台上看到更改。
man gc -par wait
告诉我没有这个参数。但我认为这并不能解决原帖作者提出的问题,因为他们要求的是 tail
而不是 tail -f
,而且还需要一个高效的实现。由于这个实现在返回最后几行前也要读取整个文件,所以对于他们期望的文件大小来说,这是很痛苦的。 - Joey为了完整起见,我会提到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
,并且它完美地起作用了。 - Paul C-Wait
参数在什么方面没有起作用? - George Mauer从PowerShell 3.0版本开始,Get-Content命令中有一个-Tail参数可用,可以帮助您解决问题。请参阅Get-Content的technet库在线帮助。
我使用了这里提供的一些答案,但需要注意的是:
Get-Content -Path Yourfile.log -Tail 30 -Wait
一段时间后,tail 命令会消耗大量内存。我的一个同事把 tail 命令运行了一整天,结果它占用了 800 MB 的内存。我不知道 Unix 的 tail 命令是否也会这样(但我觉得不会)。因此,在短期应用中可以使用它,但要小心。
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> -tail <number of items wanted> -wait
仅是之前答案的一些补充。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
我采用了@hajamie的解决方案,并将其包装成了一个更加便捷的脚本包装器。
我添加了一个选项,可以从文件结尾之前的偏移量开始读取,因此您可以使用类似tail的功能从文件末尾读取一定量的内容。请注意,偏移量是按字节计算的,而不是按行计算的。
还有一个选项可以继续等待更多内容。
示例(假设您将其保存为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 5.2(Win7和Win10)可以很容易地跟踪单个日志文件(类似于Linux中的“tail -f”),只需使用"Get-Content MyFile -Tail 1 -Wait"命令即可。但是,同时观察多个日志文件似乎比较复杂。然而,使用PowerShell 7.x+中的"Foreach-Object -Parallel"命令可以轻松解决这个问题。这将并行执行多个 'Get-Content' 命令。例如:
Get-ChildItem C:\logs\*.log | Foreach-Object -Parallel { Get-Content $_ -Tail 1 -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
}
tail
命令,有什么原因吗?请翻译此内容。 - GabeGet-Content [filename] -last 10
并添加-tail
参数即可实现-f
的功能。 - MortenB