【问题标题】:Extracting strings from String in Powershell在 Powershell 中从字符串中提取字符串
【发布时间】:2021-12-03 18:43:57
【问题描述】:

我有一个字符串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标记这个吗?
  • 但是..这基本上就是字符串中的全部内容。

标签: string powershell teamcity


【解决方案1】:

我无法为您检查 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]
}

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

此时$matchedContent 将包含您要查找的输出。如果您不希望返回匹配的第一行,也可以使用 $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 将返回 $true$false。如果$true,则可以从第一个索引中的自动变量$matches获取匹配的内容。由于数组使用从零开始的索引,这将转换为 $matches[0]

其他正则表达式技巧

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

【讨论】:

  • 谢谢@BenderTheGreatest。
【解决方案2】:

一旦您掌握了正则表达式模式,您就可以使用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

【讨论】:

  • 谢谢@Daniel。有效。非常感谢您的时间和努力。
  • 不客气。很高兴它有帮助。
【解决方案3】:

我知道这个问题已经得到解答,但这是我的两分钱:

$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

【讨论】:

  • 感谢您的所有努力@Theo!
猜你喜欢
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 2019-10-15
  • 1970-01-01
相关资源
最近更新 更多