在 Powershell 中从 String 中提取字符串
Extracting strings from String in Powershell
我有一个字符串long string: its a teamcity buildLog
这是来自 teamcity 的 buildLog。
[11:27:30] : [Step 5/5] 15:27:30 INFO: Average times: total 0.455, latency 0.455, connect 0.004
[11:27:30] : [Step 5/5] 15:27:30 INFO: Percentiles:
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | Percentile, % | Resp. Time, s |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | 0.0 | 0.021 |
[11:27:30] : [Step 5/5] | 50.0 | 0.103 |
[11:27:30] : [Step 5/5] | 90.0 | 1.166 |
[11:27:30] : [Step 5/5] | 95.0 | 2.27 |
[11:27:30] : [Step 5/5] | 99.0 | 2.77 |
[11:27:30] : [Step 5/5] | 99.9 | 6.996 |
[11:27:30] : [Step 5/5] | 100.0 | 10.312 |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] 15:27:30 INFO: Request label stats:
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | label | status | succ | avg_rt | error |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | Activity History | OK | 100.00% | 1.608 | |
[11:27:30] : [Step 5/5] | Asset Allocation | OK | 100.00% | 0.100 | |
[11:27:30] : [Step 5/5] | Dashboard Cards and Employee Information | OK | 100.00% | 0.255 | |
[11:27:30] : [Step 5/5] | Fund Details | OK | 100.00% | 0.825 | |
[11:27:30] : [Step 5/5] | Investments | OK | 100.00% | 0.132 | |
[11:27:30] : [Step 5/5] | Minimum Version | OK | 100.00% | 0.032 | |
[11:27:30] : [Step 5/5] | Rate of Return | OK | 100.00% | 0.047 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Card | OK | 100.00% | 1.166 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Full | OK | 100.00% | 1.160 | |
[11:27:30] : [Step 5/5] | Savings Rate | OK | 100.00% | 0.112 | |
[11:27:30] : [Step 5/5] | Secure Auth Login | FAIL | 98.58% | 0.207 | Bad Request |
[11:27:30] : [Step 5/5] | Validate Savings Rate Change | OK | 100.00% | 0.127 | |
[11:27:30] : [Step 5/5] | Vested Balance | OK | 100.00% | 0.157 | |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:35] : [Step 5/5] 15:27:35 INFO: Ending data feeding...
[11:27:36] : [Step 5/5] 15:27:36 INFO: Online report link: https://a.blazemeter.com/app/#/masters/36669958
从上面的构建日志中,我必须获取 Percentiles Table
、 Request Label Stats
table 和 Online Report Link
我试过下面的代码,但它正在返回 none:
$firststring = "Percentiles:"
$secondstring = "Request label stats:"
$pattern = "$firststring(.*?)$secondstring"
$result = [regex]::Match($file,$pattern).Groups[1].Value
$result >> returns none
及以下获取字符串的代码。
$Regex = [Regex]::new("(?<=Percentiles:)(.*)(?=Request label stats:)")
$Match = $Regex.Match($status)
if($Match.Success)
{
$Match.Value
}
这也是returnsnone。
任何帮助将不胜感激。
我无法为您检查 PowerShell 3.0。但以下内容适用于 Windows PowerShell 5.1。我有两个解决方案,一个包含第一条信息行作为匹配的一部分,另一个不包含。
# Set up your strings to look for
$firststring = [regex]::Escape("Percentiles:")
$secondstring = [regex]::Escape("Request label stats:")
# Pattern which includes the line with $firststring
$withInfoPattern = ".*$firststring(.*\n)*(?=.*$secondstring)"
# Pattern which omits the line with $firststring
$withoutInfoPattern = "(?<=$firststring\s+)(.*\n)*(?=.*$secondstring)"
# We will use $withInfoPattern in this example but you could also use $withoutInfoPattern
# This assumes your content string is in a variable called $content
$matchedContent = if( $content -match $withInfoPattern ) {
$matches[0]
}
This shows how to match on your first case, the Percentiles table data. To grab the second table and report link you should be able to use the code above and explanations below to extract this data as well as a learning exercise.
此时 $matchedContent
将包含您要查找的输出。如果您不希望匹配的第一行被 return 编辑,您也可以使用 $withoutInfoPattern
进行匹配。我将在下面解释:
- 虽然在这种情况下不需要,但最好将要通过
[regex]::Escape(string)
插入到正则表达式模式中的字符串放入其中。这是一个很好的做法,可以防止您将来无意中忘记使用特殊正则表达式字符对字符串进行转义。
$withInfoPattern
匹配 $firststring
前面有或没有字符的任何行。 $withoutInfoPattern
而是使用正向后视来确保匹配的内容继续出现 $firstString
.
(.*\n)*
使用捕获组来匹配任何字符或不匹配字符(这就是 .*
的意思),然后是换行符。默认情况下,换行符不与 .
匹配,并且无法使用 -match
运算符更改此行为。尾随 *
查找前面捕获组的任何实例或不查找任何实例。
-match
通常不会跨换行匹配。以这种方式使用 (.*\n)*
可以绕过该限制。
(?=.*$secondString)
是一个积极的前瞻,以确保模式主模式先于前瞻中指定的模式。 .*$secondString
将从行首开始匹配,因此我们正在查找该行上任何后跟 $secondString
的字符。
- 调用
-match
运算符在 $content
中查找 $withInfoPattern
(或 $withoutInfoPattern
)。这假设您正在搜索的字符串作为字符串存储在一个名为 $content
的变量中(而不是字符串数组,因为 Get-Content
默认情况下会这样做。
- 您可以使用
$content = Get-Content -Raw
将文件作为带有换行符的单个字符串读取,或者在匹配之前使用换行符加入 $content
数组:$content -join "`n"
-match
将 return $true
或 $false
。如果$true
,则可以从第一个索引中的自动变量$matches
中获取匹配的内容。由于数组使用从零开始的索引,因此转换为 $matches[0]
.
其他正则表达式提示
我强烈建议使用站点 https://regexr.com/ 来测试您的表达式。虽然它只支持 JavaScript 和 PCRE 引擎,但两者都足够接近 .NET regex 引擎,而它通常不支持一个问题。即使您发现某些表达式不起作用,它也能很好地解释不同的正则表达式标记,并且在您开发表达式时,它会在底部窗格中解释每个字符序列的含义。
一旦你掌握了正则表达式模式,你就可以使用 switch
到 运行 通过日志行并从你的表中构建对象。下面我将其分解为单独的函数。
$log = @'
[11:27:30] : [Step 5/5] 15:27:30 INFO: Average times: total 0.455, latency 0.455, connect 0.004
[11:27:30] : [Step 5/5] 15:27:30 INFO: Percentiles:
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | Percentile, % | Resp. Time, s |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | 0.0 | 0.021 |
[11:27:30] : [Step 5/5] | 50.0 | 0.103 |
[11:27:30] : [Step 5/5] | 90.0 | 1.166 |
[11:27:30] : [Step 5/5] | 95.0 | 2.27 |
[11:27:30] : [Step 5/5] | 99.0 | 2.77 |
[11:27:30] : [Step 5/5] | 99.9 | 6.996 |
[11:27:30] : [Step 5/5] | 100.0 | 10.312 |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] 15:27:30 INFO: Request label stats:
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | label | status | succ | avg_rt | error |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | Activity History | OK | 100.00% | 1.608 | |
[11:27:30] : [Step 5/5] | Asset Allocation | OK | 100.00% | 0.100 | |
[11:27:30] : [Step 5/5] | Dashboard Cards and Employee Information | OK | 100.00% | 0.255 | |
[11:27:30] : [Step 5/5] | Fund Details | OK | 100.00% | 0.825 | |
[11:27:30] : [Step 5/5] | Investments | OK | 100.00% | 0.132 | |
[11:27:30] : [Step 5/5] | Minimum Version | OK | 100.00% | 0.032 | |
[11:27:30] : [Step 5/5] | Rate of Return | OK | 100.00% | 0.047 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Card | OK | 100.00% | 1.166 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Full | OK | 100.00% | 1.160 | |
[11:27:30] : [Step 5/5] | Savings Rate | OK | 100.00% | 0.112 | |
[11:27:30] : [Step 5/5] | Secure Auth Login | FAIL | 98.58% | 0.207 | Bad Request |
[11:27:30] : [Step 5/5] | Validate Savings Rate Change | OK | 100.00% | 0.127 | |
[11:27:30] : [Step 5/5] | Vested Balance | OK | 100.00% | 0.157 | |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:35] : [Step 5/5] 15:27:35 INFO: Ending data feeding...
[11:27:36] : [Step 5/5] 15:27:36 INFO: Online report link: https://a.blazemeter.com/app/#/masters/36669958
'@ -split '\r?\n'
function get-percentiles {
param()
$headerPattern = '\| Percentile'
$endPattern = '^[^|+]*$'
$inTable = $false
switch -regex ($log) {
$headerPattern {
$inTable = $true
continue
}
$endPattern {
if ($inTable) { break } else { continue }
}
'\|([^|]+)\|([^|]+).*$' {
if ($inTable) {
[PSCustomObject]@{
Percentile = $Matches[1].Trim()
Time = $Matches[2].Trim()
}
}
}
}
}
function get-labeltable {
param()
$headerPattern = '\| label'
$endPattern = '^[^|+]*$'
$inTable = $false
switch -regex ($log) {
$headerPattern {
$inTable = $true
continue
}
$endPattern {
if ($inTable) { break } else { continue }
}
'\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+).*$' {
if ($inTable) {
[PSCustomObject]@{
Label = $Matches[1].Trim()
Status = $Matches[2].Trim()
Succ = $Matches[3].Trim()
AvgRT = $Matches[4].Trim()
Error = $Matches[5].Trim()
}
}
}
}
}
get-percentiles | Format-Table
get-labeltable | Format-Table
输出
Percentile Time
---------- ----
0.0 0.021
50.0 0.103
90.0 1.166
95.0 2.27
99.0 2.77
99.9 6.996
100.0 10.312
Label Status Succ AvgRT Error
----- ------ ---- ----- -----
Activity History OK 100.00% 1.608
Asset Allocation OK 100.00% 0.100
Dashboard Cards and Employee Information OK 100.00% 0.255
Fund Details OK 100.00% 0.825
Investments OK 100.00% 0.132
Minimum Version OK 100.00% 0.032
Rate of Return OK 100.00% 0.047
Retirement Outlook Card OK 100.00% 1.166
Retirement Outlook Full OK 100.00% 1.160
Savings Rate OK 100.00% 0.112
Secure Auth Login FAIL 98.58% 0.207 Bad Request
Validate Savings Rate Change OK 100.00% 0.127
Vested Balance OK 100.00% 0.157
我知道这个问题已经得到解答,但这是我的两分钱:
$log = @"
[11:27:30] : [Step 5/5] 15:27:30 INFO: Average times: total 0.455, latency 0.455, connect 0.004
[11:27:30] : [Step 5/5] 15:27:30 INFO: Percentiles:
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | Percentile, % | Resp. Time, s |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | 0.0 | 0.021 |
[11:27:30] : [Step 5/5] | 50.0 | 0.103 |
[11:27:30] : [Step 5/5] | 90.0 | 1.166 |
[11:27:30] : [Step 5/5] | 95.0 | 2.27 |
[11:27:30] : [Step 5/5] | 99.0 | 2.77 |
[11:27:30] : [Step 5/5] | 99.9 | 6.996 |
[11:27:30] : [Step 5/5] | 100.0 | 10.312 |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] 15:27:30 INFO: Request label stats:
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | label | status | succ | avg_rt | error |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | Activity History | OK | 100.00% | 1.608 | |
[11:27:30] : [Step 5/5] | Asset Allocation | OK | 100.00% | 0.100 | |
[11:27:30] : [Step 5/5] | Dashboard Cards and Employee Information | OK | 100.00% | 0.255 | |
[11:27:30] : [Step 5/5] | Fund Details | OK | 100.00% | 0.825 | |
[11:27:30] : [Step 5/5] | Investments | OK | 100.00% | 0.132 | |
[11:27:30] : [Step 5/5] | Minimum Version | OK | 100.00% | 0.032 | |
[11:27:30] : [Step 5/5] | Rate of Return | OK | 100.00% | 0.047 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Card | OK | 100.00% | 1.166 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Full | OK | 100.00% | 1.160 | |
[11:27:30] : [Step 5/5] | Savings Rate | OK | 100.00% | 0.112 | |
[11:27:30] : [Step 5/5] | Secure Auth Login | FAIL | 98.58% | 0.207 | Bad Request |
[11:27:30] : [Step 5/5] | Validate Savings Rate Change | OK | 100.00% | 0.127 | |
[11:27:30] : [Step 5/5] | Vested Balance | OK | 100.00% | 0.157 | |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:35] : [Step 5/5] 15:27:35 INFO: Ending data feeding...
[11:27:36] : [Step 5/5] 15:27:36 INFO: Online report link: https://a.blazemeter.com/app/#/masters/36669958
"@
# first parse out the link
$link = ([regex]'(?m)Online report link:\s(.*)$').Match($log).Groups[1].Value
# next remove all except the tables themselves and split into separate lines
$log = $log -replace '(?m)^[^|+]+' -split '\r?\n'
# create two List objects to capture the tables as PsObjects
$percentList = [System.Collections.Generic.List[object]]::new()
$requestList = [System.Collections.Generic.List[object]]::new()
# use switch to loop over the lines
$percentTable = $requestTable = $false
switch -Regex ($log) {
'^\|\s(Percentile|label)' {
$percentTable = ($matches[1] -eq 'Percentile')
$requestTable = !$percentTable
$headers = ($_.Trim("|") -split '\|').Trim()
continue
}
'^\|.*\|$' {
$tempHash = [ordered]@{}
$values = ($_.Trim("|") -split '\|').Trim()
for ($i = 0; $i -lt $headers.Count; $i++) {
# if you want the numeric values as [double] instead of [string] in the resulting objects, use:
# $tempHash[$headers[$i]] = if ($values[$i] -as [double]) {[double]$values[$i]} else {$values[$i]}
$tempHash[$headers[$i]] = $values[$i]
}
if ($percentTable) {
$percentList.Add([PscustomObject]$tempHash)
}
else {
$requestList.Add([PscustomObject]$tempHash)
}
}
}
# show what we have on screen
$percentList | Format-Table -AutoSize
$requestList | Format-Table -AutoSize
$link
输出:
Percentile, % Resp. Time, s
------------- -------------
0.0 0.021
50.0 0.103
90.0 1.166
95.0 2.27
99.0 2.77
99.9 6.996
100.0 10.312
label status succ avg_rt error
----- ------ ---- ------ -----
Activity History OK 100.00% 1.608
Asset Allocation OK 100.00% 0.100
Dashboard Cards and Employee Information OK 100.00% 0.255
Fund Details OK 100.00% 0.825
Investments OK 100.00% 0.132
Minimum Version OK 100.00% 0.032
Rate of Return OK 100.00% 0.047
Retirement Outlook Card OK 100.00% 1.166
Retirement Outlook Full OK 100.00% 1.160
Savings Rate OK 100.00% 0.112
Secure Auth Login FAIL 98.58% 0.207 Bad Request
Validate Savings Rate Change OK 100.00% 0.127
Vested Balance OK 100.00% 0.157
https://a.blazemeter.com/app/#/masters/36669958
我有一个字符串long string: its a teamcity buildLog
这是来自 teamcity 的 buildLog。
[11:27:30] : [Step 5/5] 15:27:30 INFO: Average times: total 0.455, latency 0.455, connect 0.004
[11:27:30] : [Step 5/5] 15:27:30 INFO: Percentiles:
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | Percentile, % | Resp. Time, s |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | 0.0 | 0.021 |
[11:27:30] : [Step 5/5] | 50.0 | 0.103 |
[11:27:30] : [Step 5/5] | 90.0 | 1.166 |
[11:27:30] : [Step 5/5] | 95.0 | 2.27 |
[11:27:30] : [Step 5/5] | 99.0 | 2.77 |
[11:27:30] : [Step 5/5] | 99.9 | 6.996 |
[11:27:30] : [Step 5/5] | 100.0 | 10.312 |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] 15:27:30 INFO: Request label stats:
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | label | status | succ | avg_rt | error |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | Activity History | OK | 100.00% | 1.608 | |
[11:27:30] : [Step 5/5] | Asset Allocation | OK | 100.00% | 0.100 | |
[11:27:30] : [Step 5/5] | Dashboard Cards and Employee Information | OK | 100.00% | 0.255 | |
[11:27:30] : [Step 5/5] | Fund Details | OK | 100.00% | 0.825 | |
[11:27:30] : [Step 5/5] | Investments | OK | 100.00% | 0.132 | |
[11:27:30] : [Step 5/5] | Minimum Version | OK | 100.00% | 0.032 | |
[11:27:30] : [Step 5/5] | Rate of Return | OK | 100.00% | 0.047 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Card | OK | 100.00% | 1.166 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Full | OK | 100.00% | 1.160 | |
[11:27:30] : [Step 5/5] | Savings Rate | OK | 100.00% | 0.112 | |
[11:27:30] : [Step 5/5] | Secure Auth Login | FAIL | 98.58% | 0.207 | Bad Request |
[11:27:30] : [Step 5/5] | Validate Savings Rate Change | OK | 100.00% | 0.127 | |
[11:27:30] : [Step 5/5] | Vested Balance | OK | 100.00% | 0.157 | |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:35] : [Step 5/5] 15:27:35 INFO: Ending data feeding...
[11:27:36] : [Step 5/5] 15:27:36 INFO: Online report link: https://a.blazemeter.com/app/#/masters/36669958
从上面的构建日志中,我必须获取 Percentiles Table
、 Request Label Stats
table 和 Online Report Link
我试过下面的代码,但它正在返回 none:
$firststring = "Percentiles:"
$secondstring = "Request label stats:"
$pattern = "$firststring(.*?)$secondstring"
$result = [regex]::Match($file,$pattern).Groups[1].Value
$result >> returns none
及以下获取字符串的代码。
$Regex = [Regex]::new("(?<=Percentiles:)(.*)(?=Request label stats:)")
$Match = $Regex.Match($status)
if($Match.Success)
{
$Match.Value
}
这也是returnsnone。 任何帮助将不胜感激。
我无法为您检查 PowerShell 3.0。但以下内容适用于 Windows PowerShell 5.1。我有两个解决方案,一个包含第一条信息行作为匹配的一部分,另一个不包含。
# Set up your strings to look for
$firststring = [regex]::Escape("Percentiles:")
$secondstring = [regex]::Escape("Request label stats:")
# Pattern which includes the line with $firststring
$withInfoPattern = ".*$firststring(.*\n)*(?=.*$secondstring)"
# Pattern which omits the line with $firststring
$withoutInfoPattern = "(?<=$firststring\s+)(.*\n)*(?=.*$secondstring)"
# We will use $withInfoPattern in this example but you could also use $withoutInfoPattern
# This assumes your content string is in a variable called $content
$matchedContent = if( $content -match $withInfoPattern ) {
$matches[0]
}
This shows how to match on your first case, the Percentiles table data. To grab the second table and report link you should be able to use the code above and explanations below to extract this data as well as a learning exercise.
此时 $matchedContent
将包含您要查找的输出。如果您不希望匹配的第一行被 return 编辑,您也可以使用 $withoutInfoPattern
进行匹配。我将在下面解释:
- 虽然在这种情况下不需要,但最好将要通过
[regex]::Escape(string)
插入到正则表达式模式中的字符串放入其中。这是一个很好的做法,可以防止您将来无意中忘记使用特殊正则表达式字符对字符串进行转义。 $withInfoPattern
匹配$firststring
前面有或没有字符的任何行。$withoutInfoPattern
而是使用正向后视来确保匹配的内容继续出现$firstString
.(.*\n)*
使用捕获组来匹配任何字符或不匹配字符(这就是.*
的意思),然后是换行符。默认情况下,换行符不与.
匹配,并且无法使用-match
运算符更改此行为。尾随*
查找前面捕获组的任何实例或不查找任何实例。-match
通常不会跨换行匹配。以这种方式使用(.*\n)*
可以绕过该限制。
(?=.*$secondString)
是一个积极的前瞻,以确保模式主模式先于前瞻中指定的模式。.*$secondString
将从行首开始匹配,因此我们正在查找该行上任何后跟$secondString
的字符。- 调用
-match
运算符在$content
中查找$withInfoPattern
(或$withoutInfoPattern
)。这假设您正在搜索的字符串作为字符串存储在一个名为$content
的变量中(而不是字符串数组,因为Get-Content
默认情况下会这样做。- 您可以使用
$content = Get-Content -Raw
将文件作为带有换行符的单个字符串读取,或者在匹配之前使用换行符加入$content
数组:$content -join "`n"
- 您可以使用
-match
将 return$true
或$false
。如果$true
,则可以从第一个索引中的自动变量$matches
中获取匹配的内容。由于数组使用从零开始的索引,因此转换为$matches[0]
.
其他正则表达式提示
我强烈建议使用站点 https://regexr.com/ 来测试您的表达式。虽然它只支持 JavaScript 和 PCRE 引擎,但两者都足够接近 .NET regex 引擎,而它通常不支持一个问题。即使您发现某些表达式不起作用,它也能很好地解释不同的正则表达式标记,并且在您开发表达式时,它会在底部窗格中解释每个字符序列的含义。
一旦你掌握了正则表达式模式,你就可以使用 switch
到 运行 通过日志行并从你的表中构建对象。下面我将其分解为单独的函数。
$log = @'
[11:27:30] : [Step 5/5] 15:27:30 INFO: Average times: total 0.455, latency 0.455, connect 0.004
[11:27:30] : [Step 5/5] 15:27:30 INFO: Percentiles:
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | Percentile, % | Resp. Time, s |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | 0.0 | 0.021 |
[11:27:30] : [Step 5/5] | 50.0 | 0.103 |
[11:27:30] : [Step 5/5] | 90.0 | 1.166 |
[11:27:30] : [Step 5/5] | 95.0 | 2.27 |
[11:27:30] : [Step 5/5] | 99.0 | 2.77 |
[11:27:30] : [Step 5/5] | 99.9 | 6.996 |
[11:27:30] : [Step 5/5] | 100.0 | 10.312 |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] 15:27:30 INFO: Request label stats:
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | label | status | succ | avg_rt | error |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | Activity History | OK | 100.00% | 1.608 | |
[11:27:30] : [Step 5/5] | Asset Allocation | OK | 100.00% | 0.100 | |
[11:27:30] : [Step 5/5] | Dashboard Cards and Employee Information | OK | 100.00% | 0.255 | |
[11:27:30] : [Step 5/5] | Fund Details | OK | 100.00% | 0.825 | |
[11:27:30] : [Step 5/5] | Investments | OK | 100.00% | 0.132 | |
[11:27:30] : [Step 5/5] | Minimum Version | OK | 100.00% | 0.032 | |
[11:27:30] : [Step 5/5] | Rate of Return | OK | 100.00% | 0.047 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Card | OK | 100.00% | 1.166 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Full | OK | 100.00% | 1.160 | |
[11:27:30] : [Step 5/5] | Savings Rate | OK | 100.00% | 0.112 | |
[11:27:30] : [Step 5/5] | Secure Auth Login | FAIL | 98.58% | 0.207 | Bad Request |
[11:27:30] : [Step 5/5] | Validate Savings Rate Change | OK | 100.00% | 0.127 | |
[11:27:30] : [Step 5/5] | Vested Balance | OK | 100.00% | 0.157 | |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:35] : [Step 5/5] 15:27:35 INFO: Ending data feeding...
[11:27:36] : [Step 5/5] 15:27:36 INFO: Online report link: https://a.blazemeter.com/app/#/masters/36669958
'@ -split '\r?\n'
function get-percentiles {
param()
$headerPattern = '\| Percentile'
$endPattern = '^[^|+]*$'
$inTable = $false
switch -regex ($log) {
$headerPattern {
$inTable = $true
continue
}
$endPattern {
if ($inTable) { break } else { continue }
}
'\|([^|]+)\|([^|]+).*$' {
if ($inTable) {
[PSCustomObject]@{
Percentile = $Matches[1].Trim()
Time = $Matches[2].Trim()
}
}
}
}
}
function get-labeltable {
param()
$headerPattern = '\| label'
$endPattern = '^[^|+]*$'
$inTable = $false
switch -regex ($log) {
$headerPattern {
$inTable = $true
continue
}
$endPattern {
if ($inTable) { break } else { continue }
}
'\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+).*$' {
if ($inTable) {
[PSCustomObject]@{
Label = $Matches[1].Trim()
Status = $Matches[2].Trim()
Succ = $Matches[3].Trim()
AvgRT = $Matches[4].Trim()
Error = $Matches[5].Trim()
}
}
}
}
}
get-percentiles | Format-Table
get-labeltable | Format-Table
输出
Percentile Time
---------- ----
0.0 0.021
50.0 0.103
90.0 1.166
95.0 2.27
99.0 2.77
99.9 6.996
100.0 10.312
Label Status Succ AvgRT Error
----- ------ ---- ----- -----
Activity History OK 100.00% 1.608
Asset Allocation OK 100.00% 0.100
Dashboard Cards and Employee Information OK 100.00% 0.255
Fund Details OK 100.00% 0.825
Investments OK 100.00% 0.132
Minimum Version OK 100.00% 0.032
Rate of Return OK 100.00% 0.047
Retirement Outlook Card OK 100.00% 1.166
Retirement Outlook Full OK 100.00% 1.160
Savings Rate OK 100.00% 0.112
Secure Auth Login FAIL 98.58% 0.207 Bad Request
Validate Savings Rate Change OK 100.00% 0.127
Vested Balance OK 100.00% 0.157
我知道这个问题已经得到解答,但这是我的两分钱:
$log = @"
[11:27:30] : [Step 5/5] 15:27:30 INFO: Average times: total 0.455, latency 0.455, connect 0.004
[11:27:30] : [Step 5/5] 15:27:30 INFO: Percentiles:
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | Percentile, % | Resp. Time, s |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] | 0.0 | 0.021 |
[11:27:30] : [Step 5/5] | 50.0 | 0.103 |
[11:27:30] : [Step 5/5] | 90.0 | 1.166 |
[11:27:30] : [Step 5/5] | 95.0 | 2.27 |
[11:27:30] : [Step 5/5] | 99.0 | 2.77 |
[11:27:30] : [Step 5/5] | 99.9 | 6.996 |
[11:27:30] : [Step 5/5] | 100.0 | 10.312 |
[11:27:30] : [Step 5/5] +---------------+---------------+
[11:27:30] : [Step 5/5] 15:27:30 INFO: Request label stats:
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | label | status | succ | avg_rt | error |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:30] : [Step 5/5] | Activity History | OK | 100.00% | 1.608 | |
[11:27:30] : [Step 5/5] | Asset Allocation | OK | 100.00% | 0.100 | |
[11:27:30] : [Step 5/5] | Dashboard Cards and Employee Information | OK | 100.00% | 0.255 | |
[11:27:30] : [Step 5/5] | Fund Details | OK | 100.00% | 0.825 | |
[11:27:30] : [Step 5/5] | Investments | OK | 100.00% | 0.132 | |
[11:27:30] : [Step 5/5] | Minimum Version | OK | 100.00% | 0.032 | |
[11:27:30] : [Step 5/5] | Rate of Return | OK | 100.00% | 0.047 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Card | OK | 100.00% | 1.166 | |
[11:27:30] : [Step 5/5] | Retirement Outlook Full | OK | 100.00% | 1.160 | |
[11:27:30] : [Step 5/5] | Savings Rate | OK | 100.00% | 0.112 | |
[11:27:30] : [Step 5/5] | Secure Auth Login | FAIL | 98.58% | 0.207 | Bad Request |
[11:27:30] : [Step 5/5] | Validate Savings Rate Change | OK | 100.00% | 0.127 | |
[11:27:30] : [Step 5/5] | Vested Balance | OK | 100.00% | 0.157 | |
[11:27:30] : [Step 5/5] +------------------------------------------+--------+---------+--------+-------------+
[11:27:35] : [Step 5/5] 15:27:35 INFO: Ending data feeding...
[11:27:36] : [Step 5/5] 15:27:36 INFO: Online report link: https://a.blazemeter.com/app/#/masters/36669958
"@
# first parse out the link
$link = ([regex]'(?m)Online report link:\s(.*)$').Match($log).Groups[1].Value
# next remove all except the tables themselves and split into separate lines
$log = $log -replace '(?m)^[^|+]+' -split '\r?\n'
# create two List objects to capture the tables as PsObjects
$percentList = [System.Collections.Generic.List[object]]::new()
$requestList = [System.Collections.Generic.List[object]]::new()
# use switch to loop over the lines
$percentTable = $requestTable = $false
switch -Regex ($log) {
'^\|\s(Percentile|label)' {
$percentTable = ($matches[1] -eq 'Percentile')
$requestTable = !$percentTable
$headers = ($_.Trim("|") -split '\|').Trim()
continue
}
'^\|.*\|$' {
$tempHash = [ordered]@{}
$values = ($_.Trim("|") -split '\|').Trim()
for ($i = 0; $i -lt $headers.Count; $i++) {
# if you want the numeric values as [double] instead of [string] in the resulting objects, use:
# $tempHash[$headers[$i]] = if ($values[$i] -as [double]) {[double]$values[$i]} else {$values[$i]}
$tempHash[$headers[$i]] = $values[$i]
}
if ($percentTable) {
$percentList.Add([PscustomObject]$tempHash)
}
else {
$requestList.Add([PscustomObject]$tempHash)
}
}
}
# show what we have on screen
$percentList | Format-Table -AutoSize
$requestList | Format-Table -AutoSize
$link
输出:
Percentile, % Resp. Time, s
------------- -------------
0.0 0.021
50.0 0.103
90.0 1.166
95.0 2.27
99.0 2.77
99.9 6.996
100.0 10.312
label status succ avg_rt error
----- ------ ---- ------ -----
Activity History OK 100.00% 1.608
Asset Allocation OK 100.00% 0.100
Dashboard Cards and Employee Information OK 100.00% 0.255
Fund Details OK 100.00% 0.825
Investments OK 100.00% 0.132
Minimum Version OK 100.00% 0.032
Rate of Return OK 100.00% 0.047
Retirement Outlook Card OK 100.00% 1.166
Retirement Outlook Full OK 100.00% 1.160
Savings Rate OK 100.00% 0.112
Secure Auth Login FAIL 98.58% 0.207 Bad Request
Validate Savings Rate Change OK 100.00% 0.127
Vested Balance OK 100.00% 0.157
https://a.blazemeter.com/app/#/masters/36669958