【问题标题】:specific text of today's date from txt file by powershellpowershell从txt文件中获取今天日期的特定文本
【发布时间】:2015-08-05 14:39:08
【问题描述】:

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

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-???(整行 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/yyyy hh:mm:ss

【问题讨论】:

    标签: powershell powershell-2.0 powershell-3.0


    【解决方案1】:

    您可以尝试将每一行转换为日期时间。然而,这不是标准的日期格式,因此[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(0001 年 1 月 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 语句不会计算为 $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")}}
    

    【讨论】:

    • 感谢您的详细解答。我试试看
    • 我测试了你的脚本,它正在解析值,但我遇到的一个问题是它只给了我一个错误。如果有多个错误,那么它不会给我所有错误的输出。
    • 一定不要使用Select-Object -First 1 语句,它只是为了显示1的输出与上下文匹配
    • 如果我使用 $Today = (Get-Date 06/06/2015).Date 和您的示例数据,我会返回 3 个对象(在 Error 属性中都具有值 Error-101
    • 感谢您的评论,但我担心可能存在多个错误 - 日期不足。您的脚本只为第一次匹配提供输出,或者 1 只能说 1 行。例如2015 年 6 月 6 日星期六 08:17:01 警告:无法删除文件。 Error-101 Error-102 这是一个示例数据。在这种情况下,您的代码无法正常工作。
    【解决方案3】:

    当您解析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}
    

    【讨论】:

    • 您的回答对我有用。我将测试一个答案,然后我会将其中一个标记为答案。非常感谢您的帮助。
    • 是否也可以从 system.txt 打印系统名称(您使用过 $_)?
    • 运行脚本时出错。 Get-ChildItem:无法评估参数“路径”,因为它的参数被指定为脚本块并且没有输入。没有输入就无法评估脚本块。
    • @404 我从Get-ChildItem -Path 中删除了{}
    • 完美运行。是什么问题。你能解释一下吗?
    【解决方案4】:

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

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

    忽略获取日期的代理功能。这只是为了让脚本处理测试数据。

    【讨论】:

    • 感谢您的帮助。我会试一试的。
    猜你喜欢
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多