2010-10-13 16 views
19

Chciałbym wyszukać więcej niż jeden ciąg znaków w plikach w katalogu, jednak użycie "select-string -pattern" nie pomogło. Czy ktoś może mi pokazać, jak to zrobić?Jak używać ciągu wyboru PowerShell, aby znaleźć więcej niż jeden wzorzec w pliku?

Przykład: Wyszukaj wszystkie pliki w C: \ Logi zawierające słowa "VendorEnquiry" i "Failed" oraz Logtime około 11:30. Struktura plików może się różnić (np. Różne nazwy znaczników itp.):

... <methodException>VendorEnquiry</methodException> ... 
... <logTime>13/10/2010T11:30:04 am</logTime> ... 
... <status>Failed</status> ... 

... <serviceMethodException>VendorEnquiry</serviceMethodException> ... 
... <logTime>13/10/2010</logTime> ... 
... <serviceStatus>Failed</serviceStatus> ... 

Dzięki.

Odpowiedz

0
+0

Nie chcę używać analizowania XML spowodowane bardzo niską wydajność dla dużych plików dziennika. Chcę czegoś tak szybko. Regex jest dobry, ale nie wiem, w jaki sposób mogę napisać wyrażenie, które znajduje się w pliku, w którym występuje słowo VendorEnquiry and Failed. – Thomas

22

Jeśli chcesz dopasować dwa słowa w dowolnej kolejności, przeznaczenie:

gci C:\Logs| select-string -pattern '(VendorEnquiry.*Failed)|(Failed.*VendorEnquiry)' 

Jeśli nie powiodło się zawsze przychodzi po VendorEnquiry na linii, wystarczy użyć:

gci C:\Logs| select-string -pattern '(VendorEnquiry.*Failed)' 
16

Aby wyszukać wiele dopasowań w każdym pliku, możemy wykonać sekwencję kilku wywołań Select-String:

Get-ChildItem C:\Logs | 
    where { $_ | Select-String -Pattern 'VendorEnquiry' } | 
    where { $_ | Select-String -Pattern 'Failed' } | 
    ... 

W każdym kroku pliki, które nie zawierają bieżącego wzorca, zostaną odfiltrowane, zapewniając, że końcowa lista plików zawiera wszystkie wyszukiwane terminy.

Zamiast ręcznie wypisując każde wezwanie Select-String, możemy uprościć ten z filtrem, aby dopasować wiele wzorów:

filter MultiSelect-String([string[]]$Patterns) { 
    # Check the current item against all patterns. 
    foreach($Pattern in $Patterns) { 
    # If one of the patterns does not match, skip the item. 
    $matched = @($_ | Select-String -Pattern $Pattern) 
    if(-not $matched) { 
     return 
    } 
    } 

    # If all patterns matched, pass the item through. 
    $_ 
} 

Get-ChildItem C:\Logs | MultiSelect-String 'VendorEnquiry','Failed',... 


Teraz, aby zaspokoić „Logtime o 11:30” część w tym przykładzie wymagałoby znalezienia czasu logowania odpowiadającego każdemu wpisowi błędu. Jak zrobić to w dużym stopniu zależy od rzeczywistej struktury plików, ale badania na „o” jest stosunkowo prosta:

function AboutTime([DateTime]$time, [DateTime]$target, [TimeSpan]$epsilon) { 
    $time -le ($target + $epsilon) -and $time -ge ($target - $epsilon) 
} 

PS> $epsilon = [TimeSpan]::FromMinutes(5) 
PS> $target = [DateTime]'11:30am' 
PS> AboutTime '11:00am' $target $epsilon 
False 
PS> AboutTime '11:28am' $target $epsilon 
True 
PS> AboutTime '11:35am' $target $epsilon 
True 
Powiązane problemy