powershell 从 txt 文件中获取今天日期的特定文本

specific text of today's date from txt file by powershell

我有一个文本文件。类似这样。

This is a sample data.
This is a sample data.
This is a sample data.
Sat Jun 06 08:17:01 2015
WARNING: Cannot delete file.
Error-101
Error-100
Error-102
This is a sample data.
This is a sample data.
Error-10666
This is a sample data.
Sat Jun 06 10:17:01 2015
File deleted.
This is a sample data.
This is a sample data.
Sat Jun 06 10:17:01 2015
File deleted.
Sat Jun 06 11:17:01 2015
WARNING: Cannot delete file.
Error-101
This is a sample data.
Sat Jun 06 18:17:01 2015
WARNING: Cannot delete file.
Error-101
This is a sample data.

此文件包含一个月的数据。 一个目录中可能有多个这样的文件。脚本需要检查今天修改的文件。

我想获取今天日期的 Error-???(整行错误-)值。 到目前为止,我已经创建了这个。

$cur_date1 = get-date -UFormat %c
$curdate = (get-date).ToString("ddMMyyyy")
ForEach ($system in (Get-Content D:\Script\system.txt)) {
        $dir = "\$system\D$\Error\"
        $latest = Get-ChildItem -Path $dir -Filter error*.txt | where{$_.LastWriteTime.ToString("ddMMyyyy") -eq $date }

$files=$latest.name
Foreach($file in $files){
         $path= $dir+$file 

        $search =  Get-Content $path 

    $a = $search| if($_ -eq $curdate){

    Where-Object{$_.Contains("Error-") }


    }

      }

}

我可以查看今天创建的文件。 我可以获得整个文件的内容。 我可以搜索错误字符串,但无法搜索当前日期。

任何人都可以就此提出建议吗?

谢谢。

如果需要对标题或说明进行任何更改,请进行更改。 谢谢你的时间。

更新

特此通知您我的系统日期时间格式如下。 dd/mm/yyyyhh:mm:ss

您可以尝试将每一行转换为日期时间。但是,这不是标准的日期格式,因此 [datetime]::TryParse() 不太可能起作用。这意味着您将需要使用 [datetime]::TryParseExact(),这有点让人恼火,因为您必须给它一个提供者和一种样式,即使您可能没有使用任何一个。

$dateString = 'Sat Jun 06 08:17:01 2015';

[System.Globalization.CultureInfo]$provider = [System.Globalization.CultureInfo]::InvariantCulture;
[System.Globalization.DateTimeStyles]$style = [System.Globalization.DateTimeStyles]::None;

$format = "ddd MMM dd HH:mm:ss yyyy";
[ref]$parsedDate = get-date;
[DateTime]::TryParseExact($dateString, $format, $provider, $style, $parsedDate);
$parsedDate.Value;

需要注意的一个关键点是 TryParse()TryParseExact() 都不是 return 值;他们 return 解析成功时为真,失败时为假。为了传递结果,您通过引用传递一个变量,函数修改引用的变量。 $parsedDate.Value 是实际日期时间值所在的位置,因为 $parsedDate 本身就是一个引用(指针)。

如果函数失败并且 return 为假,$parsedDate 的值将是 [datetime]::MinValue(0001 年 1 月 1 日)。

$curdate 是格式为 ddMMyyyy 的字符串,而日志文件中包含日期的字符串格式为 ddd MMM dd HH:mm:ss yyyy,我假设这是当前语言环境,因此您使用 Get-Date -UFormat %c.

因此,您的 if($_ -eq $curdate) 语句将不起作用。

if($_ -eq $cur_date1) will return 如果 $_ 中包含的时间戳表示脚本开始的确切秒数 运行,则为真但是随后的 Where-Object 语句不会计算为 $true (因为 $_ 当前指的是带有日期的行,而不是错误),即使它计算了,也不会 return 任何东西(你没有将任何东西传送到 Where-Object 或指定一个 InputObject 参数参数)

作为一般规则,对于日期比较,不要使用字符串表示,使用您正在比较的日期时间对象的 Date 属性。

Wrong/frail方法:

Get-ChildItem |Where-Object { $_.LastWriteTime.ToString("ddMMyyyy") -eq $datestring }

安全方法:

$today = (Get-Date).Date
Get-ChildItem |Where-Object { $_.LastWriteTime.Date -eq $today }

如果要提取错误消息的前一个日期,最简单的方法是使用 Select-StringContext 参数:

Select-String -Path C:\samplefile.log -Pattern "^Error" -Context 2 | Select-Object -First 1

  C:\samplefile.log:4:Sat Jun 06 08:17:01 2015
  C:\samplefile.log:5:WARNING: Cannot delete file.
> C:\samplefile.log:6:Error-101
  C:\samplefile.log:7:This is a sample data.
  C:\samplefile.log:8:This is a sample data.

然后您可以使用 Select-String 的输出数据来获取和比较日期:

$Today  = (Get-Date).Date
$Format = 'ddd MMM dd HH:mm:ss yyyy'
Select-String -Path C:\samplefile.log -Pattern '^Error' -Context 2 | Where-Object {
    [DateTime]::ParseExact($_.Context.PreContext[0],$Format,$null).Date -eq $Today
} | Select-Object @{Name="Error";Expression={$_.Line}},@{Name="Date";Expression={[DateTime]::ParseExact($_.Context.PreContext[0],$Format,$null).ToString("ddMMyyyy")}}

当您解析 error*.txt 文件时,您可以将上次查看日期保存在变量中。所以,当你遇到Error-*记录时,你就会知道它与什么日期有关。

$Today=[datetime]::Today
Get-Content D:\Script\system.txt|
ForEach-Object {
    $System=$_
    Get-ChildItem -Path "filesystem::\$System\D$\Error" -Filter error*.txt|
    # filesystem:: allows code to work, even if current provider is not a filesystem provider.
    Where-Object {$_.LastWriteTime.Date-eq$Today}|
    ForEach-Object {
        Get-Content -LiteralPath $_.PSPath|
        ForEach-Object {
            $ParseDate=New-Object datetime
            $LastSeenDate=$null
        } {
            if([datetime]::TryParseExact($_,'ddd MMM dd HH:mm:ss yyyy',[cultureinfo]::InvariantCulture,'None',[ref]$ParseDate)){
                $LastSeenDate=$ParseDate
            }
            if($_.StartsWith('Error-')){
                [PSCustomObject]@{
                    Error=$_
                    Date=$LastSeenDate
                    System=$System
                }
            }
        }
    }
}|
Where-Object {$_.Date.Date-eq$Today}

我收到了这个问题的回复,所以这是我的解决方案:

#Create test file from posted data:
(@'
This is a sample data.
This is a sample data.
This is a sample data.
Sat Jun 06 08:17:01 2015
WARNING: Cannot delete file.
Error-101
Error-100
Error-102
This is a sample data.
This is a sample data.
Error-10666
This is a sample data.
Sat Jun 06 10:17:01 2015
File deleted.
This is a sample data.
This is a sample data.
Sat Jun 06 10:17:01 2015
File deleted.
Sat Jun 06 11:17:01 2015
WARNING: Cannot delete file.
Error-101
This is a sample data.
Sat Jun 06 18:17:01 2015
WARNING: Cannot delete file.
Error-101
This is a sample data.
'@).split("`n") |
#where { -notmatch '^#'} |
foreach {$_.trim()} |sc testfile.txt

#Proxy function for testing
function get-date {[datetime]'06/06/2015 18:17:01'} 

#Actual solution code follows:

$DateSearch = (get-date).ToString('MMM dd [0-9:]+ yyyy(.+)')
$DateSearch = '(?ms)' + $DateSearch

if ((Get-Content testfile.txt -Raw) -match  $DateSearch)
{ $Matches[1].Split("`n") -like 'Error*' }

#remove the proxy function:
 remove-item function:get-date

Error-101
Error-100
Error-102
Error-10666
Error-101
Error-101

这使用 [datetime] tostring() 方法来帮助创建一个正则表达式来搜索文件中的今天日期。然后它捕获从该点到文件末尾的所有内容,在换行符处将其拆分并过滤掉除错误记录之外的所有内容。

忽略获取日期的代理函数。这只是为了让脚本与测试数据一起工作。