团队,提前谢谢,我是ITPro并学习PowerShell。我有一个日志文件,其中有以下格式的数据。我把照片附上去了。我正在查找已在其中完成传输的所有行,然后运行foreach循环以使用-eq运算符查找日期与当前日期匹配的行
然后,我想从运行foreach循环的当前行中获取特定的文件名。示例中的示例:日志中的第一个已完成的传输行与当前日期匹配,因此我希望获得文件名,即HardwareEvents.evtx。
但是,我无法找到任何方法来帮助我解析当前运行的每一行的文件名。
如果我得到了文件名,我可以使用powersell删除该文件。
$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"}
}

发布于 2018-11-10 12:57:34
要从日期为今天的日志中获取文件名,可以使用以下命令:
$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不同,您还可以这样做,这只需要匹配模式一次,所以在我看来要更清晰一点:
$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详细信息
^ 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)发布于 2018-11-10 17:40:57
这并不明显,但Select-String It is 可以在 ForEach-Object 脚本块E 216(不需要与-match重复匹配)中访问命令的捕获-组匹配:
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]实例的数组。
https://stackoverflow.com/questions/53237758
复制相似问题