2009-11-09 7 views
11

Ich habe den folgenden Log-Eintrag, den ich in PowerShell verarbeite Ich versuche, alle Aktivitäten Namen und Dauer mit dem Operator -match zu extrahieren, aber ich bekomme nur eine Match-Gruppe zurück. Ich bekomme nicht alle Matches, die ich sehe, wenn ich dasselbe in C# mit dem Objekt Regex mache. Kann mir jemand erklären, was ich falsch mache?PowerShell -Match-Operator und mehrere Gruppen

Relevante Powershell-Skript

$formattedMessage -match "(Get\sClient\sModel|Parse\sExpression|Get\sAbstract\sQuery|Compile\sQuery|Execute\sQuery|Get\sQuery\sPlan\sComplexity|Async\sTotal|Total)\s-\sduration\(([0-9]*)" | out-null 
$matches 

Ausgabe

Name Value 
---- ----- 
0  Get Client Model - duration(0 
1  Get Client Model 
2  0 

Protokolleintrag Beispiel:

Timestamp: 11/9/2009 6:48:41 PM 
Message: 
Category: QueryService 
Priority: 3 
EventId: 1001 
Severity: Information 
Title: SPARQL Query Response 
Machine: SPOON16-SERVER 
App Domain: KnowledgeBaseHost.exe 
ProcessId: 2040 
Process Name: D:\QueryService\QSHost.exe 
Thread Name: 
Win32 ThreadId:8092 
Extended Properties: 
Key - Workflow_cbbdd58b-e574-4054-88d4-1dd7a56dc9d9 
Timeout - 1800 
Result Format - WireTable 
Result from Registry - False 
Compiled Query from Cache - True 
Result Count - 28332 
Query Plan Complexity - 661622 
Get Client Model - duration(0) start(0) 
Parse Expression - duration(0) start(0) 
Get Abstract Query - duration(0) start(0) 
Compile Query - duration(0) start(0) 
Get Query Plan - duration(0) start(1) 
Execute Query - duration(63695) start(1) 
Get Query Plan Complexity - duration(0) start(63696) 
Get Executed Operations - duration(0) start(63696) 
Total - duration(63696) start(0) 
Async Total - duration(63696) start(0) 

Antwort

9

Sie können dies mit dem Select-String-Cmdlets in V2, aber Sie müssen angeben, die -AllMatches zB Schalter:

$formattedMessage | Select-String 'regexpattern' -AllMatches 

Beachten Sie, dass mit dem -match Operator die primäre Sache, die Sie sind doing sucht nach "a" match, dh, ob das Regex-Muster übereinstimmt oder nicht.

9

konnte ich alle Gruppen erhalten, indem eine Regex zu definieren und dann aufrufen. Spiele auf diesem Regex. Immer noch neugierig, ob dies mit dem Operator -match in der PowerShell möglich ist.

$detailRegex = [regex]"(Get\sClient\sModel|Parse\sExpression|Get\sAbstract\sQuery|Compile\sQuery|Execute\sQuery|Get\sQuery\sPlan\sComplexity|Async\sTotal|Total)\s-\sduration\(([0-9]*)" 
$detailRegex.Matches($formattedMessage) 
+0

Beste Antwort, ermöglicht es Ihnen, Ihr Ergebnis sehr einfach einer Variablen zuzuweisen, so dass Sie es einfach als ein Array von Übereinstimmungen behandeln können. – sonjz

4

Der Operator -match soll nur einmal verwendet werden; Es wird keine globale Übereinstimmung der Eingabe vorgenommen. Keith Hill legte einen Vorschlag für einen -Matchall-Operator auf Microsoft Connect here.

Ich schlage einen anderen Weg vor, es zu tun. Wenn der Protokolleintrag in einer Datei ist, können Sie die Switch-Anweisung verwenden, um die gleiche Sache zu erreichen:

switch -regex -file .\log.txt { $entryRegex { $matches[1] + ", " + $matches[2] } } 

Dies ist die Ausgabe ich mit dieser Aussage, wenn $entryRegex den regulären Ausdruck hat man definiert:

Get Client Model, 0 
Parse Expression, 0 
Get Abstract Query, 0 
Compile Query, 0 
Execute Query, 63695 
Get Query Plan Complexity, 0 
Total, 63696 
Async Total, 63696 
4

http://www.johndcook.com/regex.html gibt ein anständiges Beispiel

Und mit allen Mitteln, vereinfachen Ihr Ausdruck:

^([^-]+)\s*-\s*duration\(([0-9]+) 
  • Start am Anfang der Zeile
  • Capture alle Zeichen auf den ersten führenden up -
  • sicher, es gibt eine -
  • stellen Sie sicher, das Wort Leerzeichen überspringen „Dauer (“ existiert
  • capture alle Ziffern nach "Dauer ("
+0

Ich habe versucht, die Regex zu vereinfachen, wie du es beschrieben hast (vor dem Erstellen der fiesen, die ich dort habe) und Powershell erzeugt keine Übereinstimmungen. –

+0

Ich nahm Ihre Beispieldaten und erhielt korrekte Ergebnisse mit dem obigen Ausdruck. – genio

+0

Powershell erzeugt Übereinstimmungen mithilfe der bereitgestellten Regex –

0

Sie Regular Expression Options in einem Ausdruck enthalten können, aber leider Global scheint nicht eine der verfügbaren Optionen zu sein.