首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用select-String解析日志文件

使用select-String解析日志文件
EN

Stack Overflow用户
提问于 2018-11-10 09:47:38
回答 2查看 2.3K关注 0票数 2

团队,提前谢谢,我是ITPro并学习PowerShell。我有一个日志文件,其中有以下格式的数据。我把照片附上去了。我正在查找已在其中完成传输的所有行,然后运行foreach循环以使用-eq运算符查找日期与当前日期匹配的行

然后,我想从运行foreach循环的当前行中获取特定的文件名。示例中的示例:日志中的第一个已完成的传输行与当前日期匹配,因此我希望获得文件名,即HardwareEvents.evtx。

但是,我无法找到任何方法来帮助我解析当前运行的每一行的文件名。

如果我得到了文件名,我可以使用powersell删除该文件。

代码语言:javascript
复制
        $var = Select-String -Path "C:\Creds\AzCopyVerbose.log" -Pattern 'Finished Transfer' | `
Select-Object -Last 20 | ForEach-Object `
    {
      if (($_.Line).Substring(1,10) -eq (Get-Date).ToString('yyyy/MM/dd'))
      {
        $_.Line. // There is no method which I'm aware of need help in this if statement
      }
      Else {Write-Host "The date present in the azcopy verbose log is older"}
    }

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-10 12:57:34

要从日期为今天的日志中获取文件名,可以使用以下命令:

代码语言:javascript
复制
$logfile = 'C:\Creds\AzCopyVerbose.log'
$today = Get-Date -UFormat "%Y/%m/%d"
$pattern = '^\[(?<date>\d{4}/\d{2}/\d{2}).*Finished transfer:\s+(?<filename>.*)\s+=>.*$'
Select-String -Path $logfile -Pattern $pattern | Select-Object -Last 20 | ForEach-Object {
    $null = $_.Line -match $pattern
    if ($matches['date'] -eq $today) {
        Write-Host $matches['filename']
    }
    else {
        Write-Host "The date present in the azcopy verbose log is older"
    }
}

与使用Select-String不同,您还可以这样做,这只需要匹配模式一次,所以在我看来要更清晰一点:

代码语言:javascript
复制
$logfile = 'C:\Creds\AzCopyVerbose.log'
$today = Get-Date -UFormat "%Y/%m/%d"
$pattern = '^\[(?<date>\d{4}/\d{2}/\d{2}).*Finished transfer:\s+(?<filename>.*)\s+=>.*$'
Get-Content -Path $logfile | Select-Object -Last 20 | Where-Object { $_ -match $pattern } | ForEach-Object {
    if ($matches['date'] -eq $today) {
        Write-Host $matches['filename']
    }
    else {
        Write-Host "The date present in the azcopy verbose log is older"
    }
}

附注:我使用Get-Date -UFormat "%Y/%m/%d",因为荷兰机器上的(Get-Date).ToString('yyyy/MM/dd')输出2018-11-10

Regex详细信息

代码语言:javascript
复制
^                     Assert position at the beginning of the string
\[                    Match the character “[” literally
(?<date>              Match the regular expression below and capture its match into backreference with name “date”
   \d                 Match a single digit 0..9
      {4}             Exactly 4 times
   \/                 Match the character “/” literally
   \d                 Match a single digit 0..9
      {2}             Exactly 2 times
   \/                 Match the character “/” literally
   \d                 Match a single digit 0..9
      {2}             Exactly 2 times
)
.                     Match any single character that is not a line break character
   *                  Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
Finished\ transfer:   Match the characters “Finished transfer:” literally
\s                    Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
   +                  Between one and unlimited times, as many times as possible, giving back as needed (greedy)
(?<filename>          Match the regular expression below and capture its match into backreference with name “filename”
   .                  Match any single character that is not a line break character
      *               Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
)
\s                    Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
   +                  Between one and unlimited times, as many times as possible, giving back as needed (greedy)
=>                    Match the characters “=>” literally
.                     Match any single character that is not a line break character
   *                  Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
$                     Assert position at the end of the string (or before the line break at the end of the string, if any)
票数 2
EN

Stack Overflow用户

发布于 2018-11-10 17:40:57

补充Theo's helpful answer

这并不明显,但Select-String It is 可以在 ForEach-Object 脚本块E 216(不需要与-match重复匹配)中访问命令的捕获-组匹配:

代码语言:javascript
复制
PS> '... File transfer: C:\path\to\file => ...' |
      Select-String '\bFile transfer: (?<file>.+?) =>' | 
        ForEach-Object { $_.Matches[0].Groups['file'].Value }
C:\path\to\file  # Value of named capture group 'file' 
  • $_.Matches是当前输入行的匹配集合;除非指定了-AllMatches,否则只有一个条目,其中包含索引0
  • .Groups访问捕获组匹配的集合(在索引0处的条目包含总体匹配)。
  • ['file']访问命名捕获组file的匹配,但请注意,在基于索引的访问中(对于未命名的捕获组),从索引1开始的访问同样有效;也就是说,上面命令中的$_.Matches[0].Groups[1].Value将产生相同的结果。

在数据类型方面,Select-String发出[Microsoft.PowerShell.Commands.MatchInfo]实例,其.Matches属性是[System.Text.RegularExpressions.Match]实例的数组。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53237758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档