使用Powershell在.log中扫描最新行中的特定字符串

使用Powershell在.log中扫描最新行中的特定字符串,powershell,Powershell,我有一个.log文件,它不断地向自身添加行,我正在尝试创建一个Powershell脚本,当在.log文件的最新行中检测到相应的字符串时,该脚本将启动两个批处理脚本中的一个。以下是我目前掌握的情况: while ($True) { Write-Output 'Enter <ctrl><c> to break out of this loop.' Start-Sleep -Seconds 1 Copy-Item -LiteralPath "C

我有一个.log文件,它不断地向自身添加行,我正在尝试创建一个Powershell脚本,当在.log文件的最新行中检测到相应的字符串时,该脚本将启动两个批处理脚本中的一个。以下是我目前掌握的情况:

while ($True) {
    Write-Output 'Enter <ctrl><c> to break out of this loop.'
    Start-Sleep -Seconds 1
    Copy-Item -LiteralPath "C:\LocationOfFile\latest.log" -Destination "C:\Users\Diogo\Desktop\Detector"
    Rename-Item -Path "C:\Users\Diogo\Desktop\Detector\latest.log" -NewName "latest.txt"
    Get-Content -Path "latest.txt" -tail 1 -wait | Select-String -Quiet '§6§lP§e§lrof'
    if (System.Boolean -eq True) {
        Invoke-Item result1.bat
        Read-Host -Prompt "Press Enter to continue"
    }
    else {
        Get-Content -Path "latest.txt" -tail 1 -wait | Select-String -Quiet 'spawned'
        if (System.Boolean -eq True) {
            Invoke-Item result2.bat
            Read-Host -Prompt "Press Enter to continue"
        }
        else {
        }
    }
}
while($True){
写入输出“输入以中断此循环”
开始睡眠-秒1
复制项目-文字路径“C:\LocationOfFile\latest.log”-目标“C:\Users\Diogo\Desktop\Detector”
重命名项目-路径“C:\Users\Diogo\Desktop\Detector\latest.log”-新名称“latest.txt”
获取内容-路径“latest.txt”-尾部1-等待|选择字符串-安静“§6§lP§e§lrof”
if(System.Boolean-eq True){
调用项result1.bat
读取主机-提示“按Enter键继续”
}
否则{
获取内容-路径“latest.txt”-尾部1-等待|选择字符串-安静“繁殖”
if(System.Boolean-eq True){
调用项result2.bat
读取主机-提示“按Enter键继续”
}
否则{
}
}
}
我首先从它的位置复制.log文件,并将其更改为.txt。 然后我搜索字符串(§6§lP§e§lrof”和“生成的”) 最后我试着让它再做一次,但这似乎不像seearching那样有效

有什么帮助吗?
提前感谢首先,您的脚本无法运行有两个原因:

  • 获取内容-路径“latest.txt”-尾部1-等待|选择字符串-安静“§6§lP§e§lrof”
    Get Content-Wait
    只要读取的文件存在,或者在得到Ctrl-C'd之前,它就会一直运行,因此您的脚本永远不会超出这个范围。您可以在此处删除
    -等待
  • if(System.Boolean-eq True)
    我不明白你在这里想干什么。是否从上一个选择字符串收集结果?选择字符串本身不设置任何变量或标志。此外,您正在将类型与字符串进行比较:您在问“布尔值的概念是否等于字符串‘True’?”。您可以做的是存储Select字符串的结果,只需执行
    if($result-eq$True)
    (强调$True,而不是“True”)
此外,我将在您的脚本中重写或更正以下几件事:

  • 每秒复制一次项目
    :是否有必要?为什么不读取原始文件并将其存储在变量中?如果只是为了让您可以将扩展名从.log更改为.txt,请知道powershell并不关心扩展名,并且会乐于阅读任何内容
  • Select String
    :您是否考虑过只使用比较运算符
    -like
    ,如
    if($MyString-like“*$MyKeyword*”){…}
  • If块不需要Else块。如果你的Else什么都不做,你就不能写了。还有一个elseif块,您可以使用它来代替链接else和if
  • 代码风格:请选择一个并坚持它。我大部分时间看到的是1TB,但K&R或Allman也很有名。我可能会也可能不会要求对你的问题进行编辑以获得一些缩进:p
因此,我们最终得出以下结论:

while ($True) {
    Write-Output 'Enter <ctrl><c> to break out of this loop.'
    Start-Sleep -Seconds 1
    $LastLogLine = Get-Content -Path "C:\LocationOfFile\latest.log" -tail 1
    if ($LastLogLine -like '*§6§lP§e§lrof*') {
        Invoke-Item result1.bat
        Read-Host -Prompt "Press Enter to continue"
    } elseif ($LastLogLine -like '*spawned*') {
        Invoke-Item result2.bat
        Read-Host -Prompt "Press Enter to continue"
    }
}

非常感谢您的全面回复,这确实帮助我掌握了一些Powershell概念,而且它工作得完美无缺。你能帮我回答关于这个剧本的最后一个问题吗?不管怎样,谢谢!这帮了我很多的忙!
while ($True) {
    Write-Output 'Enter <ctrl><c> to break out of this loop.'
    Start-Sleep -Seconds 1
    $LastLogLine = Get-Content -Path "C:\LocationOfFile\latest.log" -tail 1
    if ($LastLogLine -like '*§6§lP§e§lrof*') {
        Invoke-Item result1.bat
        Read-Host -Prompt "Press Enter to continue"
    } elseif ($LastLogLine -like '*spawned*') {
        Invoke-Item result2.bat
        Read-Host -Prompt "Press Enter to continue"
    }
}
  $stream = Start-Job -ArgumentList $LogPath -Name "StreamFileContent" -ScriptBlock {Get-Content $args -Wait}
  Receive-Job -Job $Stream                              # Discard everything that was already written in the file, we only want the stuff that is added to the file after we've started.
  while($true) {                                        # As long as the script is left running
      foreach($NewLine in (Receive-Job -Job $stream)) { # Fetch the lines that Get-Content gave us since last loop
          if ($NewLine -like '*§6§lP§e§lrof*') {        # Check for your keyword
              C:\MyScriptPath\MyScript1.bat             # Start batch script
          } elseif ($NewLine -like '*spawned*') {
              C:\MyScriptPath\MyScript2.bat
          }
      }
  }