如何解决如何查看文件,每当它发生变化时,采用新的附加行并使用 powershell 对其执行一些操作
如何查看日志文件,每次添加一行时,我想重新格式化该行并使用 Invoke-RestMethod(基本上使用 discord 作为日志文件)将其广播到 webhook,然后可能还输出一些/相同的信息到控制台。
这与其他人提出的类似问题类似。我一直在尝试这样做 2 周。在以下帖子中,他们回答了大部分问题:
Watch file for changes and run command with powershell
但是,它没有显示如何将添加的行添加到文件中并对它执行所有操作,同时它仍在等待日志文件使用下一个条目再次更新。日志文件可以连续快速更新,因此当程序对检测到的更改执行所述操作时,如果日志文件发生其他更改,则不确定这些方法是否会跟上更改。
到目前为止,我一直在循环中尝试这样的事情(这不是整个代码):
get-content '<file-name>' -tail 1 -wait
但是看起来这可能会连续遗漏行,因为在处理附加操作时,可能会出现更多行。所以看起来我可能需要以更复杂的方式执行此操作(没关系)。只是想弄清楚该往哪个方向走。
解决方法
您所做的只是允许在屏幕上实时显示文件。你不能弄乱输出这样做。
您使用的命令不适用于交互式用例。
您可以通过使用 SystemFileWatcher 监控文件更新,而无需执行您正在执行的操作,它允许监控文件操作,然后您可以对其进行操作。
'PowerShell filesystemwatcher 监控文件'
https://duckduckgo.com/?q=%27PowerShell+filesystemwatcher+monitor+file%27&t=h_&ia=web
例如来自上述链接的点击之一。
https://powershell.one/tricks/filesystem/filesystemwatcher
监视文件夹的文件更改
使用 FileSystemWatcher,您可以监视文件夹中的文件更改和 当检测到变化时立即响应。这样,你可以 创建“drop”文件夹并响应日志文件更改。
具体来说,根据您的用例:
高级模式(异步)
如果您希望更改快速连续发生,甚至 同时,您可以异步使用 FileSystemWatcher 模式:FileSystemWatcher 现在在后台工作,不再 阻止 PowerShell。相反,每当发生变化时,事件就会发生 提高。所以用这种方法,你会得到一个队列,不会错过任何一个 改变。
在背面,这种方法有两个挑战:
-
处理事件:由于 PowerShell 本质上是单线程的,因此 响应事件不简单,调试起来更麻烦 事件处理程序代码。
保持 PowerShell 运行:讽刺的是,因为 FileSystemWatcher 现在不再阻止 PowerShell,这会导致另一个问题。你 需要让 PowerShell 等待事件,但您不能使用 Start-Sleep 或无限循环,因为只要 PowerShell 很忙
- 即使它处于睡眠状态也被认为是忙碌的 - 无法处理任何事件。
实施
下面的脚本和同步版本做的完全一样 从上面看,只有它是基于事件的,不会再错过任何事件:
# find the path to the desktop folder:
$desktop = [Environment]::GetFolderPath('Desktop')
# specify the path to the folder you want to monitor:
$Path = $desktop
# specify which files you want to monitor
$FileFilter = '*'
# specify whether you want to monitor subfolders as well:
$IncludeSubfolders = $true
# specify the file or folder properties you want to monitor:
$AttributeFilter = [IO.NotifyFilters]::FileName,[IO.NotifyFilters]::LastWrite
try
{
$watcher = New-Object -TypeName System.IO.FileSystemWatcher -Property @{
Path = $Path
Filter = $FileFilter
IncludeSubdirectories = $IncludeSubfolders
NotifyFilter = $AttributeFilter
}
# define the code that should execute when a change occurs:
$action = {
# the code is receiving this to work with:
# change type information:
$details = $event.SourceEventArgs
$Name = $details.Name
$FullPath = $details.FullPath
$OldFullPath = $details.OldFullPath
$OldName = $details.OldName
# type of change:
$ChangeType = $details.ChangeType
# when the change occured:
$Timestamp = $event.TimeGenerated
# save information to a global variable for testing purposes
# so you can examine it later
# MAKE SURE YOU REMOVE THIS IN PRODUCTION!
$global:all = $details
# now you can define some action to take based on the
# details about the change event:
# let's compose a message:
$text = "{0} was {1} at {2}" -f $FullPath,$ChangeType,$Timestamp
Write-Host ""
Write-Host $text -ForegroundColor DarkYellow
# you can also execute code based on change type here:
switch ($ChangeType)
{
'Changed' { "CHANGE" }
'Created' { "CREATED"}
'Deleted' { "DELETED"
# to illustrate that ALL changes are picked up even if
# handling an event takes a lot of time,we artifically
# extend the time the handler needs whenever a file is deleted
Write-Host "Deletion Handler Start" -ForegroundColor Gray
Start-Sleep -Seconds 4
Write-Host "Deletion Handler End" -ForegroundColor Gray
}
'Renamed' {
# this executes only when a file was renamed
$text = "File {0} was renamed to {1}" -f $OldName,$Name
Write-Host $text -ForegroundColor Yellow
}
# any unhandled change types surface here:
default { Write-Host $_ -ForegroundColor Red -BackgroundColor White }
}
}
# subscribe your event handler to all event types that are
# important to you. Do this as a scriptblock so all returned
# event handlers can be easily stored in $handlers:
$handlers = . {
Register-ObjectEvent -InputObject $watcher -EventName Changed -Action $action
Register-ObjectEvent -InputObject $watcher -EventName Created -Action $action
Register-ObjectEvent -InputObject $watcher -EventName Deleted -Action $action
Register-ObjectEvent -InputObject $watcher -EventName Renamed -Action $action
}
# monitoring starts now:
$watcher.EnableRaisingEvents = $true
Write-Host "Watching for changes to $Path"
# since the FileSystemWatcher is no longer blocking PowerShell
# we need a way to pause PowerShell while being responsive to
# incoming events. Use an endless loop to keep PowerShell busy:
do
{
# Wait-Event waits for a second and stays responsive to events
# Start-Sleep in contrast would NOT work and ignore incoming events
Wait-Event -Timeout 1
# write a dot to indicate we are still monitoring:
Write-Host "." -NoNewline
} while ($true)
}
finally
{
# this gets executed when user presses CTRL+C:
# stop monitoring
$watcher.EnableRaisingEvents = $false
# remove the event handlers
$handlers | ForEach-Object {
Unregister-Event -SourceIdentifier $_.Name
}
# event handlers are technically implemented as a special kind
# of background job,so remove the jobs now:
$handlers | Remove-Job
# properly dispose the FileSystemWatcher:
$watcher.Dispose()
Write-Warning "Event Handler disabled,monitoring ends."
}
因此,根据上述内容,您可以对其进行调整以查找更新/修改,然后使用
$CaptureLine = Get-Content -Path 'UNCToTheLogFile' | Select-Object -Last 1
或
$CaptureLine = Get-Content -Path 'D:\temp\book1.csv' -Tail 1
然后做你想做的事。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。