从文档计算时间

时间:2016-12-19 13:26:25

标签: powershell

my previous question的基础上(感谢@MartinBrandl),我想抓住时间值来计算时间。

示例数据:

07:30 - 07:45PMTS09526052 | Sev9 | Location| | Due: 12/23/2016
NON PC HARDWARE - TROUBLESHOOT SW
Complete this Job

Martin Brandl想出了这个以获得我需要的其他数据:

Select-String $WLDir -pattern '(PMT[S|T]\d{8})' -Context 0,2 | ForEach-Object {
[PSCustomObject]@{
    Time = $_.Matches.Groups[1].Value
    Topic = $_.Context.PostContext[0]
    Status = $_.Context.PostContext[1]
}
} | ConvertTo-Csv -NoTypeInformation

我想在07:30 - 07:45部分之前抓住PMT位。我打算用它来抽出时间:

$StartTime = [However I get the `7:30` here]
$EndTime = [However I get the `7:45` here]
$ElapsedTime = (NEW-TIMESPAN –Start $StartTime –End $EndTime).TotalHours

我要在CSV中添加第四个字段:

Elapsed = $ElapsedTime

但我不确定如何具体抓住两次并将它们隔离为变量。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

在你的第一个问题中,时间跨度不是在Csv中 因为它没有被RegEx引用。现在它和7:30 是$ matches.groups [1] .value等等

$WLDir = ".\File.txt" 
$Pattern='(\d{2}:\d{2}) - (\d{2}:\d{2})(PMT[S|T]\d{8})'
Select-String $WLDir -pattern $Pattern -Context 0,2 |
    ForEach-Object {
        $StartTime=[datetime]::ParseExact($_.Matches.Groups[1].Value,"HH:mm",$null)
        $EndTime=[datetime]::ParseExact($_.Matches.Groups[2].Value,"HH:mm",$null)
        $ElapsedTime = (NEW-TIMESPAN –Start $StartTime –End $EndTime).TotalHours
        [PSCustomObject]@{
            Time = $_.Matches.Groups[3].Value
            Topic = $_.Context.PostContext[0]
            Status = $_.Context.PostContext[1]
            ElapsedHrs = $ElapsedTime
        }
} | ConvertTo-Csv -NoTypeInformation

给出这个输出(我在PMTT中添加了第二个测试版)

"Time","Topic","Status","ElapsedHrs"
"PMTS09526052","NON PC HARDWARE - TROUBLESHOOT SW","Complete this Job","0,25"
"PMTT10952605","NON PC HARDWARE - TROUBLESHOOT SW","Complete this Job","0,25"

列时间仍然不包含时间 (我的语言环境有一个小数逗号)

答案 1 :(得分:1)

Ansgar Wiechers提供了关于该问题的评论中的关键指针(将捕获组(\d{2}:\d{2})添加到正则表达式中捕获时间字符串,例如07:30)和LotPing's helpful answer充实它们一个直接使Nate代码工作的工作解决方案。

让我提供一个更简洁的替代方案,使用PowerShell的类型加速器和强制转换:

Select-String $WLDir -pattern '(\d{2}:\d{2}) - (\d{2}:\d{2})(PMT[ST]\d{8})' -Context 0,2 |
    ForEach-Object {
        [pscustomobject] @{
            Time = $_.Matches.Groups[3].Value
            Topic = $_.Context.PostContext[0]
            Status = $_.Context.PostContext[1]
            Elapsed = (
             [datetime] $_.Matches.Groups[2].Value - [datetime] $_.Matches.Groups[1].Value
            ).TotalHours
        }
    } | ConvertTo-Csv -NoTypeInformation $OutFile
  • 将通过前2个捕获组($_.Matches.Groups[1].Value$_.Matches.Groups[2].Value)捕获的时间字符串转换为[datetime],将它们转换为[datetime]System.DateTime )时间部分反映指定时间的实例(其 date 部分默认为今天)。

  • 您可以直接从另一个实例中减去[datetime]个实例来获取它们之间的时间跨度:结果是[timespan]System.TimeSpan)实例,其{{1}然后可以访问属性。

请注意,解决方案假设PM值以24小时格式表示(例如,下午3点必须表示为.TotalHours)。