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