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