programing

Select-String에서 캡처된 그룹을 가져오려면 어떻게 해야 합니까?

lovejava 2023. 4. 9. 20:53

Select-String에서 캡처된 그룹을 가져오려면 어떻게 해야 합니까?

Powershell(버전 4)을 사용하여 Windows의 파일 세트에서 텍스트를 추출하려고 합니다.

PS > Select-String -AllMatches -Pattern <mypattern-with(capture)> -Path file.jsp | Format-Table

지금까지는 좋아.그것은 좋은 세트를 준다.MatchInfo오브젝트:

IgnoreCase                    LineNumber Line                          Filename                      Pattern                       Matches
----------                    ---------- ----                          --------                      -------                       -------
    True                            30   ...                           file.jsp                      ...                           {...}

다음으로 캡처가 매치멤버에 있는 것을 확인하고 꺼냅니다.

PS > Select-String -AllMatches -Pattern <mypattern-with(capture)> -Path file.jsp | ForEach-Object -MemberName Matches | Format-Table

그 결과:

Groups        Success Captures                 Index     Length Value
------        ------- --------                 -----     ------ -----
{...}         True    {...}                    49        47     ...

또는 목록으로| Format-List:

Groups   : {matched text, captured group}
Success  : True
Captures : {matched text}
Index    : 39
Length   : 33
Value    : matched text

여기서 멈추겠습니다. 어떻게 하면 캡처된 그룹 요소의 목록을 얻을 수 있을지 모르겠습니다.

다른 것을 추가하려고 했습니다.| ForEach-Object -MemberName Groups그러나 위와 같은 결과가 반환되는 것 같습니다.

내가 가장 가까이 가는 것은| Select-Object -Property Groups기대했던 대로입니다(세트 리스트).

Groups
------
{matched text, captured group}
{matched text, captured group}
...

하지만 각각에서 잡힌 그룹을 추출할 수 없습니다| Select-Object -Index 1나는 그 세트들 중 하나만 받는다.


업데이트: 가능한 해결책

더하면 더해지는 것 같다.| ForEach-Object { $_.Groups.Groups[1].Value }찾고 있던 것은 얻었지만, 그 이유를 알 수 없기 때문에, 이 방법을 파일 세트 전체로 확장할 때 올바른 결과를 얻을 수 있을지 확신할 수 없습니다.

왜 이렇게 되지?

참고로 이건| ForEach-Object { $_.Groups[1].Value }(즉, 두 번째가 없는 경우).Groups)에서도 같은 결과가 나타납니다.

추가 시도 시 파이프를 제거함으로써 명령어를 단축할 수 있을 것으로 생각됩니다.| Select-Object -Property Groups.

다음을 참조하십시오.

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

$a이제 가 되었다.MatchInfo($a.gettype())가 포함되어 있습니다.Matches소유물.

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/

찾고 있는 것을 찾을 수 있으므로 다음과 같이 쓸 수 있습니다.

"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

[정규 표현(Regular Expressions)]> [그룹(Groups), 캡처(Captures), 치환(Substitutions)]의 powershell 문서에 따르면

를 사용하는 경우-match연산자, powershell이 자동변수를 만듭니다.

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

이 식에서 반환되는 값은 다음과 같습니다.true|false단, PS는$Matches 해시 테이블

출력하면$Matches, 모든 캡처 그룹을 가져옵니다.

PS> $Matches

Name     Value
----     -----
2        CONTOSO\jsmith
1        The last logged on user was
0        The last logged on user was CONTOSO\jsmith

또한 다음과 같은 도트 표기로 각 캡처 그룹에 개별적으로 액세스할 수 있습니다.

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

기타 자원:

이게 내 처지에 먹혔어.

file: test를 사용합니다.txt

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

파일에서 NUMBER와 VERSION을 가져옵니다.

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

응답이 늦었지만 사용하는 여러 일치 및 그룹을 루프하려면:

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

이 스크립트는 파일의 내용에서 regex의 지정된 캡처 그룹을 가져와 일치 항목을 콘솔에 출력합니다.


$file입니다.
$cg입니다.
$regex 패턴입니다.



로드할 파일 및 내용 예:

C:\some\file.txt

This is the especially special text in the file.



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

★★★★★special text


get_regex_regex.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 }

언급URL : https://stackoverflow.com/questions/33913878/how-to-get-the-captured-groups-from-select-string