web-dev-qa-db-fra.com

Comment obtenir les groupes capturés à partir de Select-String?

J'essaie d'extraire du texte d'un ensemble de fichiers sous Windows à l'aide de Powershell (version 4):

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

Jusqu'ici tout va bien. Cela donne un bel ensemble d'objets MatchInfo:

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

Ensuite, je vois que les captures sont dans le membre des allumettes, alors je les retire:

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

Qui donne:

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

ou sous forme de liste avec | Format-List:

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

Voici où je m'arrête, je ne sais pas comment aller plus loin et obtenir une liste d'éléments groupe capturé.

J'ai essayé d'ajouter un autre | ForEach-Object -MemberName Groups, Mais il semble revenir comme ci-dessus.

Je me rapproche le plus de | Select-Object -Property Groups, Ce qui me donne ce à quoi je m'attendais (une liste de jeux):

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

Mais alors je suis incapable d'extraire le groupe capturé de chacun d'eux, j'ai essayé avec | Select-Object -Index 1 Je ne reçois qu'un de ces ensembles.


Mise à jour: une solution possible

Il semble qu'en ajoutant | ForEach-Object { $_.Groups.Groups[1].Value } J'ai obtenu ce que je cherchais, mais je ne comprends pas pourquoi. Je ne peux donc pas être sûr d'obtenir le bon résultat en étendant cette méthode à des ensembles entiers. de fichiers.

Pourquoi ça marche?

En remarque, ce | ForEach-Object { $_.Groups[1].Value } (C'est-à-dire sans le second .Groups) Donne le même résultat.

Je voudrais ajouter que, lors de nouvelles tentatives, il semble que la commande peut être raccourcie en supprimant le piped | Select-Object -Property Groups.

41
watery

Regardez ce qui suit

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

$a Est maintenant un MatchInfo ($a.gettype()), il contient une propriété 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/

dans les membres du groupe, vous trouverez ce que vous recherchez pour pouvoir écrire:

"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
45
JPBlanc

Ce script va extraire le groupe de capture spécifié d'une expression régulière du contenu d'un fichier et en afficher les correspondances sur la console.


$file Est le fichier que vous voulez charger
$cg Est le groupe de capture que vous souhaitez capturer
$regex Est le modèle d'expression régulière



Exemple de fichier et de son contenu à charger:

C:\certains\fichier.txt

This is the especially special text in the file.



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

Sortie: 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
kayleeFrye_onDeck