2009-03-05 11 views
18

Ho un file di testo contenente righe di dati. Posso utilizzare il seguente script PowerShell per estrarre le righe che mi interessano:Come si estrae il valore di un riferimento/corrispondenza regex in PowerShell

select-string -path *.txt -pattern "subject=([A-Z\.]+)," 

Alcuni dati esempio potrebbe essere:

blah blah subject=THIS.IS.TEST.DATA, blah blah blah 

Quello che voglio è quello di essere in grado di estrarre solo il contenuto effettivo del soggetto (cioè la stringa "THIS.IS.TEST.DATA"). Ho provato questo:

select-string -path *.txt -pattern "subject=([A-Z\.]+)," | %{ $_.Matches[0] } 

Ma la proprietà "Corrispondenze" è sempre nullo. Che cosa sto facendo di sbagliato?

risposta

9

Non so il motivo per cui la versione non funziona. Dovrebbe funzionare. Ecco una versione più brutta che funziona.

$p = "subject=([A-Z\.]+)," 
select-string -path *.txt -pattern $p | % {$_ -match $p > $null; $matches[1]} 

Modifica. Spiegazione per dante:

-match è un regolare operatore di espressione matching:

>"foobar" -match "oo.ar" 
True 

Il > $null sopprime solo il vero essere inviate in output. (Provare a rimuoverlo.) C'è un cmdlet che fa la stessa cosa di cui non ricordo il nome al momento.

$matches è una variabile magica che contiene il risultato dell'ultima operazione -match.

+0

Grazie, che funziona, ma potrebbe spiegare quello che stai facendo? In particolare il bit "$ _ -match $ p> $ null". – d4nt

+1

Il cmdlet dangph sta pensando a "Out-Null". Ma puoi anche trasmettere l'intera riga a [void]: [void] ($ _ -match $ p) – JasonMArcher

2

Il problema con il codice che si sta digitando è che select-string non trasmette l'oggetto Regex reale. Invece passa una classe diversa chiamata MatchInfo che non ha la regex effettiva corrispondente alle informazioni.

Se si desidera eseguire la regex una sola volta, sarà necessario eseguire il rollup della propria funzione che non è troppo difficile.

function Select-Match() { 
    param ($pattern = $(throw "Need a pattern"), 
     $filePath = $(throw "Need a file path")) 
    foreach ($cur in (gc $filePath)) { 
    if ($cur -match $pattern) { 
     write-output $matches[0]; 
    } 
    } 
} 

gci *.txt | %{ Select-Match "subject=([A-Z\.]+)," $_.FullName } 
+0

Ma perché la proprietà MatchInfo.Matches non funziona? http://msdn.microsoft.com/en-us/library/microsoft.powershell.commands.matchinfo.matches(VS.85).aspx –

+0

@dangph, credo che sia un bug nei documenti. Puoi verificarlo eseguendo "gci a * .txt | gm". Il tipo risultante non ha proprietà Matches. – JaredPar

+0

JaredPar, non ha funzionato per me, ma credo che tu abbia ragione. Prova questo: "gm -inputobject (new-object Microsoft.PowerShell.Commands.MatchInfo)". –

2

Ancora un'altra opzione

gci *.txt | foreach { [regex]::match($_,'(?<=subject=)([^,]+)').value } 
2

Dopo aver imparato molto da tutte le altre risposte sono stato in grado di ottenere ciò che voglio utilizzando la seguente riga:

gci *.txt | gc | %{ [regex]::matches($_, "subject=([A-Z\.]+),") } | %{ $_.Groups[1].Value } 

questo sembrava bello come Stavo solo eseguendo un'espressione regolare una volta per riga e mentre inserivo questo comando al prompt dei comandi era bello non avere più righe di codice.

+0

Felice di aver trovato una soluzione. Ho appena controllato in v2 e la proprietà Matches funziona con Select-String. Quindi in futuro questo sarà meno doloroso per te. :) – JasonMArcher

0

Un'altra variante, corrispondenti 7 cifre in una stringa

echo "123456789 hello test" | % {$_ -match "\d{7}" > $null; $matches[0]} 

ritorni: 1234567

4

in PowerShell V2 CTP3, la proprietà Risultati è implementato.Così il proceda in questo modo:

select-string -path *.txt -pattern "subject=([A-Z\.]+)," | %{ $_.Matches[0].Groups[1].Value } 
1

Il comando Select-String sembra restituire un MatchInfo variabile variabile e non una "stringa". Ho passato diverse ore a scoprirlo sui forum e sul sito ufficiale senza fortuna. Sto ancora raccogliendo informazioni. Un modo per aggirare questo è quello di dichiarare esplicitamente una variabile stringa per contenere il risultato restituito dalla Select-String, dal vostro esempio:

[stringa] $ foo = select-stringa -path * .txt -pattern " subject = ([AZ.] +), "

La variabile $ pippo è ora una stringa e non un oggetto MatchInfo.

Spero che questo aiuti.

PS5 PowerShell versione 5 stringa stringhe di manipolazione