String PowerShell字符串定时

String PowerShell字符串定时,string,windows,powershell,String,Windows,Powershell,我想获取以下字符串,并以某种方式对其进行解析,以输出每个步骤的长度。时间以hr:min:sec的形式列出 编辑所需输出: [步骤2]花了2分钟完成 [测试3]花了3分3秒完成 [示例4]花了3分钟完成 编辑后要求单独输出$content括号中的每一行项目,而不是简单地列出“步骤” $Content = [Step1]::14:37:11 [Step2]::14:39:11 [Test3]::14:42:14 [Example4]::14:45:14 在本例中,我将从$content中的字符串

我想获取以下字符串,并以某种方式对其进行解析,以输出每个步骤的长度。时间以hr:min:sec的形式列出

编辑所需输出:

[步骤2]花了2分钟完成

[测试3]花了3分3秒完成

[示例4]花了3分钟完成

编辑后要求单独输出$content括号中的每一行项目,而不是简单地列出“步骤”

$Content =

[Step1]::14:37:11
[Step2]::14:39:11
[Test3]::14:42:14
[Example4]::14:45:14

在本例中,我将从
$content
中的字符串创建一个TimeSpan对象数组,并将其用于输出

如果
$content
是一个数组,请立即使用它。
如果
$content
是单个字符串,则需要首先使用
$content=$content-split'\r?\n'

# assuming $content is a single string, so we need to split into array:
$Content = @"

[Step1]::14:37:11
[Step2]::14:39:11
[Step3]::14:42:14
[Step4]::14:45:09
[Step5]::14:57:12
"@ -split '\r?\n'
下一个循环遍历此字符串数组并删除空行(如果有):

$times = $content | Where-Object { $_ -match '\S' } | ForEach-Object {
    $h, $m, $s = ($_.Trim() -replace '.*(\d{2}:\d{2}:\d{2})$', '$1') -split ':'
    [TimeSpan]::new([int]$h, [int]$m, [int]$s)
}

for ($i = 1; $i -lt $times.Count; $i++) {
    $timeDiff = $times[$i] - $times[$i - 1]
    # output the times taken for each step
    "Step $($i + 1) took $($timeDiff.ToString()) to complete."
}
输出:

Step 2 took 00:02:00 to complete. Step 3 took 00:03:03 to complete. Step 4 took 00:02:55 to complete. Step 5 took 00:12:03 to complete. [Step2] took 2 minutes to complete [Test3] took 3 minutes to complete [Example4] took 3 minutes to complete
根据您在评论中的新要求,以下是稍作修改的代码:

$Content = @"

[Step1]::14:37:11
[Step2]::14:39:11
[Test3]::14:42:14
[Example4]::14:45:14
"@ -split '\r?\n'

$times = $content | Where-Object { $_ -match '\S' } | ForEach-Object {
    # capture the action like '[Example4]' and the timestamp part
    $action, $processTime = $_.Trim() -split '::'
    # split the timestamp into Hours, Minutes, Seconds 
    $h, $m, $s = ($processTime -replace '.*(\d{2}:\d{2}:\d{2})$', '$1') -split ':'
    # output an object with two properties, the action name and a TimeSpan
    [PsCustomObject]@{
        'Action' = $action
        'Time'   = [TimeSpan]::new([int]$h, [int]$m, [int]$s)
    }
}

# loop through the returned array, get the time difference between steps
for ($i = 1; $i -lt $times.Count; $i++) {
    $timeDiff = $times[$i].Time - $times[$i - 1].Time
    # output the times taken for each step, in this new requirement rounded to show minutes only
    '{0} took {1} minutes to complete' -f $times[$i].Action, [math]::Round($timeDiff.TotalMinutes, 0)
}
输出:

Step 2 took 00:02:00 to complete. Step 3 took 00:03:03 to complete. Step 4 took 00:02:55 to complete. Step 5 took 00:12:03 to complete. [Step2] took 2 minutes to complete [Test3] took 3 minutes to complete [Example4] took 3 minutes to complete [步骤2]花了2分钟完成 [Test3]花了3分钟完成 [示例4]花了3分钟完成
这里有一个稍微不同的方式到达那里。。。[咧嘴笑]

它的作用

  • 创建一组要使用的时间信息行
    准备好真正执行此操作后,删除整个
    #region/#endregion
    块,并用调用
    获取内容
    替换它
  • 过滤掉没有时间信息字符串的行
  • 迭代从@1开始到集合上限结束的行
    这将跳过
    [step1]
    ,因为您所需的输出指示计时信息是每个步骤的结束
  • 从上一个数组项获取开始时间
  • 从当前数组项中获取步骤名称和结束时间
  • 使用
    -f
    字符串格式运算符生成字符串
  • 通过将时间信息转换为
    timespan
    对象并从结束处减去开始,计算经过的时间
  • 将其发送到屏幕
我试图将信息放入PSCustomObjects数组中,但您似乎只需要字符串输出。[咧嘴笑]

代码

#region >>> fake reading in a text file
#    in real life, use Get-Content
$InStuff = @'
$Content =

[Step1]::14:37:11
[Step2]::14:39:11
[Step3]::14:42:14
[Step4]::14:45:09
[Step5]::14:57:12
'@ -split [System.Environment]::NewLine
#endregion >>> fake reading in a text file

# get rid of the no-time-info lines
$TimeLines = $InStuff -match '::'

foreach ($Index in 1..$TimeLines.GetUpperBound(0))
    {
    $StartTime = ($TimeLines[$Index - 1] -split '::')[-1]
    $Step, $EndTime = $TimeLines[$Index] -split '::'

    '{0} took {1} [hh:mm:ss] to complete.' -f $Step, ([timespan]$EndTime - [timespan]$StartTime)
    }
输出

[Step2] took 00:02:00 [hh:mm:ss] to complete.
[Step3] took 00:03:03 [hh:mm:ss] to complete.
[Step4] took 00:02:55 [hh:mm:ss] to complete.
[Step5] took 00:12:03 [hh:mm:ss] to complete.

这里有什么内容?原始文本?数组?显示的时间是每个步骤的开始还是结束?你想要的结果表明时间是每一步的终点。谢谢你,西奥!在我最初的问题中添加了一个额外的请求,标记为粗体。。。你能看看这个提奥吗?@Joseph-不客气![grin]Theo的解决方案似乎更稳健。。。我很高兴你
接受了它
我把内容存储在一个变量$TestFile中。。。文件路径为c:\windows\testfile.txt。您的脚本需要如何修改才能解决简单地调用变量而不是伪读文本文件的问题?正如我在注释中提到的,将整个“伪”块替换为调用
Get Content
,以将文件加载到
$InStuff
变量中。另外,您可以将$Var重命名为任何适合您的名称。我使用
$InStuff
作为默认的“没有更好的名称”变量名。。。[咧嘴笑]