Как использовать строку выбора PowerShell для поиска более одного шаблона в файле?
Я хотел бы искать более одной строки в файлах в каталоге, но использование "select-string -pattern" не помогло. Может ли кто-нибудь показать мне, как это сделать?
Пример: Поиск всех файлов в C:\Журналах, содержащих слова "VendorEnquiry" и "Failed", а также с Logtime около 11:30. Структура файлов может отличаться (например, разные имена тегов и т.д.):
... <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> ...
Спасибо.
Ответы
Ответ 1
Если вы хотите совместить два слова в любом порядке, используйте:
gci C:\Logs| select-string -pattern '(VendorEnquiry.*Failed)|(Failed.*VendorEnquiry)'
Если Failed всегда приходит после VendorEnquiry в строке, просто используйте:
gci C:\Logs| select-string -pattern '(VendorEnquiry.*Failed)'
Ответ 2
Чтобы найти несколько совпадений в каждом файле, мы можем выполнить несколько вызовов Select-String:
Get-ChildItem C:\Logs |
where { $_ | Select-String -Pattern 'VendorEnquiry' } |
where { $_ | Select-String -Pattern 'Failed' } |
...
На каждом шаге файлы, которые не содержат текущий шаблон, будут отфильтрованы, гарантируя, что окончательный список файлов содержит все условия поиска.
Вместо того, чтобы записывать каждый вызов Select-String вручную, мы можем упростить это с помощью фильтра, который будет соответствовать нескольким шаблонам:
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',...
Теперь, чтобы удовлетворить "Logtime около 11:30 утра", часть примера потребует поиска времени журнала, соответствующего каждой записи об ошибке. Как это сделать, сильно зависит от фактической структуры файлов, но тестирование для "about" относительно просто:
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
Ответ 3
Вы можете указать несколько шаблонов в массиве.
select-string VendorEnquiry,Failed C:\Logs
Ответ 4
Как использовать регулярное выражение в powershell?
http://powershell.com/cs/blogs/ebook/archive/2009/03/30/chapter-13-text-and-regular-expressions.aspx
Разбор XML может быть лучшим решением.
http://thepowershellguy.com/blogs/posh/archive/2007/12/30/processing-xml-with-powershell.aspx