Powershell 使用select字符串分析日志文件

Powershell 使用select字符串分析日志文件,powershell,Powershell,团队, 提前感谢,我是一名IT专业人士,正在学习PowerShell。我有一个日志文件,其中包含以下格式的数据。我已经附上了这张照片。 我正在查找所有在其中完成传输的行,然后运行foreach循环,使用-eq运算符查找日期与当前日期匹配的行 然后,我想从运行foreach循环的当前行中获取特定的文件名。示例来自我的示例:日志中第一个完成的传输线与当前日期匹配,因此我希望获得文件名HardwareEvents.evtx 但是我找不到任何方法可以帮助我解析当前运行的每一行的文件名 如果获得文件名,则

团队, 提前感谢,我是一名IT专业人士,正在学习PowerShell。我有一个日志文件,其中包含以下格式的数据。我已经附上了这张照片。 我正在查找所有在其中完成传输的行,然后运行foreach循环,使用-eq运算符查找日期与当前日期匹配的行

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

但是我找不到任何方法可以帮助我解析当前运行的每一行的文件名

如果获得文件名,则可以使用powersell cmdlet删除该文件

        $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"}
    }

下面是一种使用regex表示日期的方法

$var = Select-String -Path "C:\Creds\AzCopyVerbose.log" -Pattern 'Finished Transfer' | 
Select-Object -Last 20 | ForEach-Object -Process {
      $_.Line -match '\d{4}/\d{2}/\d{2}' | Out-Null
      [string]$Match = $Matches.Values
      if ([Datetime]$Match -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"}
    }

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

$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"
    }
}
p、 我使用
获取日期-UFormat“%Y/%m/%d”
是因为
(获取日期).ToString('yyyy/MM/dd')
在我的荷兰机器输出上
2018-11-10

正则表达式详细信息

^                     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)
^在字符串开头断言位置
\[按字面意思匹配字符“[”
(?匹配下面的正则表达式,并将其匹配捕获到名为“date”的backreference中
\d匹配单个数字0..9
{4} 正好4次
\/按字面意思匹配字符“/”
\d匹配单个数字0..9
{2} 正好两次
\/按字面意思匹配字符“/”
\d匹配单个数字0..9
{2} 正好两次
)
.匹配不是换行符的任何单个字符
*在零次和无限次之间,尽可能多次,根据需要回馈(贪婪)
完成\传输:按字面意思匹配字符“完成传输”:
\s匹配单个“空白字符”(空格、制表符、换行符等)
+在一次和无限次之间,尽可能多次,根据需要回馈(贪婪)
(?匹配下面的正则表达式,并将其匹配捕获到名为“filename”的backreference中
.匹配不是换行符的任何单个字符
*在零次和无限次之间,尽可能多次,根据需要回馈(贪婪)
)
\s匹配单个“空白字符”(空格、制表符、换行符等)
+在一次和无限次之间,尽可能多次,根据需要回馈(贪婪)
=>按字面意思匹配字符“=>”
.匹配不是换行符的任何单个字符
*在零次和无限次之间,尽可能多次,根据需要回馈(贪婪)
$Assert位置位于字符串末尾(或字符串末尾的换行符之前,如果有)
补充:

这并不明显,但可以访问
ForEach对象
脚本块中
Select String
命令的[named]捕获组匹配(无需重复与
-match
匹配):

PS>“…文件传输:C:\path\to\File=>…”|
选择字符串“\b文件传输:(?。+?)=>”|
ForEach对象{$\.Matches[0]。组['file'].Value}
C:\path\to\file#命名捕获组“file”的值
  • $\u.Matches
    是当前输入行的匹配项集合;除非指定了
    -AllMatches
    ,否则只有一个条目,索引为
    0

  • .Groups
    访问捕获组匹配项的集合(索引
    0
    中的条目包含整体匹配项)

  • ['file']
    访问命名捕获组的匹配项
    文件
    ,但请注意,at基于索引的访问同样有效(对于未命名捕获组),从索引
    1开始;也就是说,
    $.Matches[0].groups[1]。上述命令中的值
    将产生相同的结果


就数据类型而言,
Select String
会发出实例,其
。Matches
属性是一个实例数组。

请将要搜索的数据以文本形式发布,而不是图片形式发布。我认为一个可能带有look arounds的正则表达式可以通过捕获组过滤相关文件名。首先,感谢Theo教授me一个新的方法来实现这一点,我今天学到了一件新的事情。再次感谢。我只想知道一件事,你是如何创建regex模式的?你能通过一个链接或你创建它的方式来指导我吗?这会很有帮助。再次感谢。@aquib.rocks我已经为regex添加了详细信息。我总是使用RegexBuddy(不是免费的…),但是你也可以在你身上做实验,你真是太棒了,我的朋友,我很困惑,当你还没有写任何代码的时候,正则表达式是如何知道文件名的。但是现在我通过你的解释知道,它自动知道=>之前的任何东西都是通过正则表达式的文件名。(?*)\s+=>.$'感谢brother提供的所有帮助。很好,但是即使使用
选择字符串
,您也不必进行两次匹配,因为您可以通过
$.Matches[0]访问捕获组。组
,例如,
$.Matches[0]。组['filename'].Value
。您不必求助于Unix日期格式来确保
/
的文字使用;只需
\
-转义它(或使用嵌入的引用):
获取日期-格式“yyyy\/MM\/dd”
我的荣幸,@aquib.rocks。我添加了一段链接到答案所涉及的数据类型。
^                     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)
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'