【问题标题】:Powershell convert string to datePowershell 将字符串转换为日期
【发布时间】:2018-12-14 04:50:01
【问题描述】:

我正在整理一些自定义监控解决方案,并且日志包含不同的日期/时间条目。尝试从日志中解析日期/时间(文本值)并转换为日期值,以便我可以与其他人或系统日期进行比较。我过去使用过以下内容,但在更改为允许单个数字 DD 值和 12 小时时钟值时遇到了麻烦。

$line = "=== 2018-01-07 03:30:25,889 [ng)'] INFO"

$dateTimeString = [regex]::Matches($line, '(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)')[0].Groups[1].Value

$provider = New-Object System.Globalization.CultureInfo "en-US"

$dateTime = [datetime]::ParseExact($dateTimeString, 'yyyy-MM-dd HH:mm:ss', $provider)

但需要转换以下内容。

$line = "错误 - 2018 年 1 月 7 日 2:13:19 AM EST - 警告"

我确定 parseexact 将是: $dateTime = [datetime]::ParseExact($dateTimeString, 'MMM d, yyyy h:mm:ss tt', 提供者)

但我无法使用 Matches 函数将文本解析为这些值。

编辑: 在利用比尔的建议后,明确分配变量时,它可以工作。但是,当我将 Get-Content 假脱机到变量时,它不会。

$line = Get-Content $SBWebPath | Select-String $SBError -casesensitive |select -last 1
Write-Output $line
$line | Select-String '^####<(\S+ \S+, \S+ \S+ \S+) \S+> <Warning>' | ForEach-Object {
$dateTime = $_.Matches[0].Groups[1].Value -as [DateTime]
}
$dateTime

输出:

####<Dec 7, 2017 5:17:26 AM EST> <Warning> <HTTP>

编辑2:

如 Bill 所述,$line 被转换为数组,因此 ForEach-Object 无法解析数组。通过添加 | Out-String 到行尾,然后它就能够将其解析为字符串。

有效的最终代码:

$line = Get-Content $SBWebPath | Select-String $SBError -casesensitive | Select -last 1 | Out-String
Write-Output $line
$line | Select-String '^####<(\S+ \S+, \S+ \S+ \S+) \S+> <Warning>' | ForEach-Object {
$dateTime = $_.Matches[0].Groups[1].Value -as [DateTime]
}
$dateTime

大家干杯。

【问题讨论】:

    标签: powershell datetime


    【解决方案1】:

    这是一种(相当短的)方法:

    $line = "Error - Jan 7, 2018 2:13:19 AM EST - Warning"
    $line | Select-String '^Error - (\S+ \S+, \S+ \S+ \S+) \S+ -' | ForEach-Object {
      $dateTime = $_.Matches[0].Groups[1].Value -as [DateTime]
    }
    $dateTime
    

    这种方法的一个警告是您会丢失时区信息。

    要对整个文件执行此操作,您可以编写类似以下内容:

    Get-Content file.txt | ForEach-Object {
      # $_ here means "current line from input file"
      $_ | Select-String '^Error - (\S+ \S+, \S+ \S+ \S+) \S+ -' | ForEach-Object {
        # $_ here means "current MatchInfo object"
        $_.Matches[0].Groups[1].Value -as [DateTime]
      }
    }
    

    【讨论】:

    • 我用过这个,它似乎工作得很好。但是现在如果我不明确声明 $line ,它就无法转换。请参阅上面的编辑。
    • 如果你写$line = Get-Content file.txt,如果文件包含一行,$line变量将只包含一行;否则,它将包含一个数组。您可以使用ForEach-Object 来迭代Get-Content 的输出,无论它是否包含单行或数组。 $_ 表示“管道中的当前项目”。查看更新的答案。
    【解决方案2】:

    我使用 Get-Date 命令将字符串转换为日期,避免了文化设置或本地计算机设置方面的问题。

    引用来自 URL https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date?view=powershell-6 的示例 4

    (Get-Date -Year 2000 -Month 12 -Day 31).DayOfYear
    

    我使用命令 LastWriteTime 更新了文件的修改日期。我解析了文件名以获取日期和时间。

    $_.LastWriteTime = Get-Date -Year $y -Month $m -Day $d -Hour $h -Minute $n -Second $s
    

    我为整个文件目录更新修改日期的代码如下。我已经包含了我在构建这个脚本期间使用的所有额外的 echo 语句。希望这种冗长可以帮助您更好地理解每个步骤。

    Get-ChildItem 'C:\*.jpg' | ForEach-Object {
    
        # File Info
        echo $_.FullName
        echo $_.BaseName
        echo $_.BaseName.IndexOf(" . ")
        echo $_.BaseName.SubString(26,17)
        $y = $_.BaseName.SubString(26,4)
        $m = $_.BaseName.SubString(31,2)
        $d = $_.BaseName.SubString(34,2)
        $h = $_.BaseName.SubString(37,2)
        $n = $_.BaseName.SubString(39,2)
        $s = $_.BaseName.SubString(41,2)
        $date = "$y,$m,$d,$h,$n,$s"
        echo $date
    
        # Modified Date
        echo $_.LastWriteTime
    
        # Update Modified Date
        $_.LastWriteTime = Get-Date -Year $y -Month $m -Day $d -Hour $h -Minute $n -Second $s
        echo $_.LastWriteTime
    }
    

    【讨论】:

      猜你喜欢
      • 2017-01-07
      • 2015-04-27
      • 2016-10-27
      • 1970-01-01
      • 2011-11-28
      • 2016-05-03
      相关资源
      最近更新 更多