2009-04-29 7 views
28

Próbuję znaleźć wzór w plikach. Kiedy dostaję mecz używając Select-String nie chcę całej linii, po prostu chcę części, która pasowała.Jak mogę zwrócić tylko pasujące wyrażenie regularne, gdy wybieram ciąg (grep) w PowerShell?

Czy istnieje parametr, którego mogę użyć, aby to zrobić?

Na przykład:

Gdybym zrobił

select-string .-.-. 

a plik zawierał linię z:

abc 1-2-3 abc 

Chciałbym uzyskać wynik tylko 1-2 -3 zamiast zwracania całej linii.

Chciałbym wiedzieć równowartość PowerShell o grep -o

Odpowiedz

20

Dawida na właściwej ścieżce. [Regex] jest akcelerator typu dla System.Text.RegularExpressions.Regex

[regex]$regex = '.-.-.' 
$regex.Matches('abc 1-2-3 abc') | foreach-object {$_.Value} 
$regex.Matches('abc 1-2-3 abc 4-5-6') | foreach-object {$_.Value} 

Można owinąć że w zależności czy to jest zbyt rozwlekły.

+0

Dzięki to działało idealnie! – Skyler

15

Próbowałem inne podejście: Select-String zwraca właściwość Mecze, których można użyć. Aby uzyskać wszystkie dopasowania, musisz podać -AllMatches. W przeciwnym razie zwraca tylko pierwszy.

Moja zawartość pliku testu:

test test1 alk atest2 asdflkj alj test3 test 
test test3 test4 
test2 

Skrypt:

select-string -Path c:\temp\select-string1.txt -Pattern 'test\d' -AllMatches | % { $_.Matches } | % { $_.Value } 

powraca

test1 #from line 1 
test2 #from line 1 
test3 #from line 1 
test3 #from line 2 
test4 #from line 2 
test2 #from line 3 

Select-String at technet.microsoft.com

+1

Nie mogłem uzyskać tego działającego, mam tylko dostęp do PS 1.0 i nie wygląda to tak: -AllMatches jest rozpoznawany co najmniej w 1.0. W każdym razie dzięki! – Skyler

+0

Hmm, pracuję z v2, ctp3. Nie mam możliwości, aby spróbować rozwiązać to na v1, przepraszam .. – stej

+1

Obsługa dopasowań została dodana w wersji 2 oprócz kontekstu. – JasonMArcher

9

W duchu teach a man to fish ...

To, co chcesz zrobić, to potokować dane wyjściowe polecenia select-string w Get-member, aby zobaczyć, jakie właściwości mają obiekty. Gdy to zrobisz, zobaczysz "Mecze" i możesz wybrać tylko to, wysyłając wyniki do | **Select-Object** Matches.

Moja sugestia jest użycie czegoś podobnego: wybierz LineNumber, nazwy pliku, zapałki

Na przykład: na próbce stej za:

sls .\test.txt -patt 'test\d' -All |select lineNumber,fileName,matches |ft -auto 

LineNumber Filename Matches 
---------- -------- ------- 
     1 test.txt {test1, test2, test3} 
     2 test.txt {test3, test4} 
     3 test.txt {test2} 
33

Lub po prostu:

Select-String .-.-. .\test.txt -All | Select Matches