从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 TableRequest Label Stats表和Online Report Link

我尝试了以下代码,但没有返回:

$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
}

这也不会返回任何值。任何帮助都将不胜感激。

我无法为您检查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 = "(?<=$firststrings+)(.*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]
}

这显示了如何在第一种情况下匹配百分位数表数据。要获取第二个表和报告链接,您应该能够使用上面的代码和下面的解释来提取这些数据以及学习练习。

此时$matchedContent将包含您要查找的输出。如果不希望返回匹配的第一行,也可以使用$withoutInfoPattern进行匹配。我将在下面对此进行解释:

  • 虽然在这种情况下不是必需的,但最好将要通过[regex]::Escape(string)插入regex模式的字符串放入。这是一个很好的做法,可以防止您在将来无意中忘记使用特殊regex字符转义字符串
  • CCD_ 8在CCD_ 9前面有或没有字符的任何行上匹配。CCD_ 10反而使用正的后备来确保匹配的内容继续发生CCD_ 11
  • (.*n)*使用一个捕获组来匹配任何字符或不匹配任何字符(这就是.*的意思),然后是一条换行符。默认情况下,换行符与.不匹配,并且-match运算符无法更改此行为。尾随的CCD_ 16查找前一捕获组的任何实例或不查找前一个捕获组的实例。
    • -match通常不会跨换行符匹配。以这种方式使用(.*n)*可以绕过这个限制
  • CCD_ 19是确保模式主模式先于在前瞻中指定的模式的正向前瞻。.*$secondString将与该行的开头匹配,因此我们正在查找该行上任何后面跟着$secondString的字符
  • 调用-match运算符在$content中查找$withInfoPattern(或$withoutInfoPattern)。这假设您正在搜索的字符串作为字符串存储在一个名为$content的变量中(而不是默认情况下Get-Content所做的字符串数组)。
    • 您可以使用$content = Get-Content -Raw将文件作为带有换行符的单个字符串读取,或者在匹配之前使用换行符连接$content数组:$content -join "`n"
  • -match将返回$true$false。如果是$true,则可以从第一个索引中的自动变量$matches中获取匹配的内容。由于数组使用基于零的索引,因此这转换为$matches[0]

其他Regex提示

我强烈建议使用该网站https://regexr.com/测试中的表达式。虽然这只支持JavaScript和PCRE引擎,但两者都非常接近.NET正则表达式引擎,这通常不是问题。即使您发现某些表达式不起作用,它也会很好地解释不同的regex标记,并且在开发表达式时,它会在底部窗格中解释每个字符序列的含义。

一旦您确定了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