2009-11-09 18 views
11

Ho la seguente voce di registro che sto elaborando in PowerShell Sto tentando di estrarre tutti i nomi di attività e le durate usando l'operatore -match ma sto recuperando solo un gruppo di corrispondenza. Non ricevo tutte le corrispondenze che vedo quando faccio la stessa cosa in C# usando l'oggetto Regex. Qualcuno può spiegare cosa sto sbagliando?PowerShell -match operator e più gruppi

Rilevante PowerShell Script

$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 

uscita

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

voce del registro Esempio:

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) 

risposta

9

Si può fare questo con il cmdlet Select-String in V2, ma è necessario specificare le -AllMatches passare ad esempio:

$formattedMessage | Select-String 'regexpattern' -AllMatches 

Tenete presente che con l'operatore -match la cosa primaria si è fare sta cercando la corrispondenza "a", vale a dire che il modello regex è uguale o meno.

9

sono stato in grado di ottenere tutti i gruppi definendo un Regex e quindi chiamando. Partite su quel Regex. Ancora curioso di sapere se questo può essere fatto con l'operatore -match in PowerShell.

$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

risposta migliore, consente di assegnare il risultato a una variabile molto facilmente in modo da poterlo gestire come una serie di corrispondenze. – sonjz

4

L'operatore -match è pensato per essere utilizzato solo una volta; non fa una corrispondenza globale sull'input. Keith Hill ha inviato un suggerimento per un operatore di -matchall su Microsoft connect here.

Ti suggerisco un altro modo per farlo. Se la voce di registro è in un file, è possibile utilizzare l'istruzione switch per ottenere la stessa cosa:

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

Questa è l'uscita ottengo con questa affermazione, se $entryRegex ha l'espressione regolare si è definito:

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 dà un esempio decente

E, con tutti i mezzi, semplificare la tua espressione:

^([^-]+)\s*-\s*duration\(([0-9]+) 
  • avvio all'inizio della riga
  • cattura tutti i caratteri che portano al primo -
  • assicurarsi che ci sia un -
  • skip salta spazi
  • assicurarsi che la parola "durata (" esiste
  • cattura tutte le cifre dopo "durata ("
+0

Ho provato a semplificare la regex come descritto (prima di crearne uno cattivo) e PowerShell non genera alcuna corrispondenza. –

+0

Ho preso i vostri dati di esempio e stavo ottenendo risultati corretti con l'espressione esatta sopra. – genio

+0

powershell genererà le corrispondenze utilizzando la regex fornita –

0

È possibile includere Regular Expression Options in un'espressione, ma purtroppo, globale non sembra essere una delle opzioni disponibili.