How to get the captured groups from Select-String?

前端 未结 5 758
清酒与你
清酒与你 2020-12-05 16:41

I\'m trying to extract text from a set of files on Windows using the Powershell (version 4):

PS > Select-String -AllMatches -Pattern 

        
相关标签:
5条回答
  • 2020-12-05 17:29

    Have a look at the following

    $a = "http://192.168.3.114:8080/compierews/" | Select-String -Pattern '^http://(.*):8080/(.*)/$' 
    

    $a is now a MatchInfo ($a.gettype()) it contain a Matches property.

    PS ps:\> $a.Matches
    Groups   : {http://192.168.3.114:8080/compierews/, 192.168.3.114, compierews}
    Success  : True
    Captures : {http://192.168.3.114:8080/compierews/}
    Index    : 0
    Length   : 37
    Value    : http://192.168.3.114:8080/compierews/
    

    in the groups member you'll find what you are looking for so you can write :

    "http://192.168.3.114:8080/compierews/" | Select-String -Pattern '^http://(.*):8080/(.*)/$'  | % {"IP is $($_.matches.groups[1]) and path is $($_.matches.groups[2])"}
    
    IP is 192.168.3.114 and path is compierews
    
    0 讨论(0)
  • 2020-12-05 17:29

    According to the powershell docs on Regular Expressions > Groups, Captures, and Substitutions:

    When using the -match operator, powershell will create an automatic variable named $Matches

    PS> "The last logged on user was CONTOSO\jsmith" -match "(.+was )(.+)"
    

    The value returned from this expression is just true|false, but PS will add the $Matches hashtable

    So if you output $Matches, you'll get all capture groups:

    PS> $Matches
    
    Name     Value
    ----     -----
    2        CONTOSO\jsmith
    1        The last logged on user was
    0        The last logged on user was CONTOSO\jsmith
    

    And you can access each capture group individually with dot notation like this:

    PS> "The last logged on user was CONTOSO\jsmith" -match "(.+was )(.+)"
    PS> $Matches.2
    CONTOSO\jsmith
    

    Additional Resources:

    • To Get Multiple Matches, see How to capture multiple regex matches
    • To Pass Options/Flags, see Pass regex options to PowerShell [regex] type
    0 讨论(0)
  • 2020-12-05 17:33

    Late answer, but to loop multiple matches and groups I use:

    $pattern = "Login:\s*([^\s]+)\s*Password:\s*([^\s]+)\s*"
    $matches = [regex]::Matches($input_string, $pattern)
    
    foreach ($match in $matches)
    {
        Write-Host  $match.Groups[1].Value
        Write-Host  $match.Groups[2].Value
    }
    
    0 讨论(0)
  • 2020-12-05 17:38

    This worked for my situation.

    Using the file: test.txt

    // autogenerated by script
    char VERSION[21] = "ABCDEFGHIJKLMNOPQRST";
    char NUMBER[16] = "123456789012345";
    

    Get the NUMBER and VERSION from the file.

    PS C:\> Select-String -Path test.txt -Pattern 'VERSION\[\d+\]\s=\s\"(.*)\"' | %{$_.Matches.Groups[
    1].value}
    
    ABCDEFGHIJKLMNOPQRST
    
    PS C:\> Select-String -Path test.txt -Pattern 'NUMBER\[\d+\]\s=\s\"(.*)\"' | %{$_.Matches.Groups[1
    ].value}
    
    123456789012345
    
    
    0 讨论(0)
  • 2020-12-05 17:41

    This script will grab a regex's specified capture group from a file's content and output its matches to console.


    $file is the file you want to load
    $cg is capture group you want to grab
    $regex is the regular expression pattern



    Example file and its content to load:

    C:\some\file.txt

    This is the especially special text in the file.



    Example Use: .\get_regex_capture.ps1 -file "C:\some\file.txt" -cg 1 -regex '\b(special\W\w+)'

    Output: special text


    get_regex_capture.ps1

    Param(
        $file=$file,
        [int]$cg=[int]$cg,
        $regex=$regex
    )
    [int]$capture_group = $cg
    $file_content = [string]::Join("`r`n", (Get-Content -Raw "$file"));
    Select-String -InputObject $file_content -Pattern $regex -AllMatches | % { $_.Matches.Captures } | % { echo $_.Groups[$capture_group].Value }
    
    0 讨论(0)
提交回复
热议问题