powershell

时间:2015-08-03 10:37:04

标签: powershell powershell-v2.0 powershell-v3.0

我有一个文本文件。与此类似。

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.

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

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

$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 / yyyy hh:mm:ss

4 个答案:

答案 0 :(得分:2)

您可以尝试将每一行转换为日期时间。但是,这不是标准的日期格式,因此[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()都不会返回值;解析成功时返回True,失败时返回False。为了传递结果,您通过引用传递变量,函数修改引用的变量。 $parsedDate.Value是实际日期时间值的位置,因为$parsedDate本身是一个引用(指针)。

如果函数失败并返回false,$parsedDate的值将为[datetime]::MinValue(1月1日,0001)。

答案 1 :(得分:2)

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

因此,您的if($_ -eq $curdate)声明无法发挥作用。

如果if($_ -eq $cur_date1)中包含的时间戳代表您的脚本开始运行的确切秒数,则

$_ 返回true,但随后的Where-Object语句赢得了' t评估为$true(因为$_目前指的是带有日期的行,而不是错误),即使它确实如此,也不会返回任何内容(您还没有管道输入)任何Where-Object或指定InputObject参数参数)

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

错误/虚弱的做法:

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

答案 2 :(得分:1)

在解析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}

答案 3 :(得分:1)

我得到了这个问题,所以这是我对解决方案的看法:

#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()方法来帮助创建正则表达式以在文件中搜索今天的日期。然后它捕获从该点到文件末尾的所有内容,将其拆分为换行符并过滤除错误记录之外的所有内容。

忽略get-date的代理函数。这就是让脚本使用测试数据。