Ich versuche, mit Powershell (Version 4) Text aus einer Reihe von Dateien unter Windows zu extrahieren:
PS > Select-String -AllMatches -Pattern <mypattern-with(capture)> -Path file.jsp | Format-Table
So weit, ist es gut. Das gibt eine schöne Reihe von MatchInfo
Objekten:
IgnoreCase LineNumber Line Filename Pattern Matches
---------- ---------- ---- -------- ------- -------
True 30 ... file.jsp ... {...}
Als nächstes sehe ich, dass sich die Captures im Match-Mitglied befinden, also nehme ich sie heraus:
PS > Select-String -AllMatches -Pattern <mypattern-with(capture)> -Path file.jsp | ForEach-Object -MemberName Matches | Format-Table
Welches gibt:
Groups Success Captures Index Length Value
------ ------- -------- ----- ------ -----
{...} True {...} 49 47 ...
oder als Liste mit | Format-List
:
Groups : {matched text, captured group}
Success : True
Captures : {matched text}
Index : 39
Length : 33
Value : matched text
Hier höre ich auf. Ich habe keine Ahnung, wie ich weiter gehen und eine Liste der erfassten Gruppenelemente erhalten soll .
Ich habe versucht, ein weiteres hinzuzufügen | ForEach-Object -MemberName Groups
, aber es scheint dasselbe wie oben zurückzugeben.
Am nächsten komme ich mit | Select-Object -Property Groups
, was mir tatsächlich das gibt, was ich erwarten würde (eine Liste von Sets):
Groups
------
{matched text, captured group}
{matched text, captured group}
...
Aber dann kann ich die erfasste Gruppe nicht aus jedem von ihnen extrahieren. Ich habe versucht | Select-Object -Index 1
, nur eines dieser Sets zu erhalten.
Update: eine mögliche Lösung
Es scheint, dass | ForEach-Object { $_.Groups.Groups[1].Value }
ich durch Hinzufügen das bekommen habe, wonach ich gesucht habe, aber ich verstehe nicht warum - daher kann ich nicht sicher sein, ob ich das richtige Ergebnis erzielen kann, wenn ich diese Methode auf ganze Dateigruppen ausdehne.
Warum funktioniert es?
Als Randnotiz ergibt dies | ForEach-Object { $_.Groups[1].Value }
(dh ohne die Sekunde .Groups
) das gleiche Ergebnis.
Ich möchte hinzufügen, dass bei weiteren Versuchen der Befehl anscheinend durch Entfernen der Rohrleitungen verkürzt werden kann | Select-Object -Property Groups
.
quelle
0
, die selbst ein Match ist. In IhrerGroups
Fallkollektion gibt es also zwei Elemente: Übereinstimmung mit sich selbst und erste Erfassungsgruppe. Wenn Sie nur eine Gruppe erfassen möchten, müssen Sie diese mit angebenGroups[1]
.Antworten:
Schauen Sie sich Folgendes an
$a = "http://192.168.3.114:8080/compierews/" | Select-String -Pattern '^http://(.*):8080/(.*)/$'
$a
ist jetzt einMatchInfo
($a.gettype()
) es enthält eineMatches
Eigenschaft.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/
Im Gruppenmitglied finden Sie, wonach Sie suchen, damit Sie schreiben können:
"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
quelle
$a
) nicht angezeigt . Ich habe versucht zu bearbeiten, habe aber eine Fehlermeldung erhalten, da meine Bearbeitung weniger als sechs Zeichen umfasst. IOW, erscheinen die Einfanggruppen als(.)
statt(.*)
wie beabsichtigt.%
ist ein Alias fürForEach-Object
. dann können Sie jedes Objekt mit behandeln$_
.Gemäß den Powershell-Dokumenten zu regulären Ausdrücken> Gruppen, Erfassungen und Ersetzungen :
Bei Verwendung des
-match
Operators erstellt Powershell eine automatische Variable mit dem Namen$Matches
PS> "The last logged on user was CONTOSO\jsmith" -match "(.+was )(.+)"
Der von diesem Ausdruck zurückgegebene Wert ist nur
true
|false
, aber PS wird die Hashtabelle hinzufügen$Matches
Wenn Sie also ausgeben
$Matches
, erhalten Sie alle Erfassungsgruppen:Und Sie können auf jede Erfassungsgruppe einzeln mit der folgenden Punktnotation zugreifen:
PS> "The last logged on user was CONTOSO\jsmith" -match "(.+was )(.+)" PS> $Matches.2 CONTOSO\jsmith
Zusätzliche Ressourcen :
[regex]
Typquelle
Das hat für meine Situation funktioniert.
Verwenden der Datei: test.txt
// autogenerated by script char VERSION[21] = "ABCDEFGHIJKLMNOPQRST"; char NUMBER[16] = "123456789012345";
Holen Sie sich die NUMMER und die VERSION aus der Datei.
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
quelle
Späte Antwort, aber um mehrere Übereinstimmungen und Gruppen zu wiederholen, verwende ich:
$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 }
quelle
Dieses Skript greift die angegebene Erfassungsgruppe eines regulären Ausdrucks aus dem Inhalt einer Datei ab und gibt die Übereinstimmungen an die Konsole aus.
$file
Ist die Datei, die Sie laden möchten,$cg
ist die Erfassungsgruppe, die Sie abrufen möchten,$regex
das Muster für reguläre AusdrückeBeispieldatei und ihr zu ladender Inhalt:
C: \ some \ file.txt
This is the especially special text in the file.
Beispiel Verwendung:
.\get_regex_capture.ps1 -file "C:\some\file.txt" -cg 1 -regex '\b(special\W\w+)'
Ausgabe:
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 }
quelle