#regex #powershell
#регулярное выражение #powershell
Вопрос:
краткое:
$logFile="D:Codefunctest1725.log"
function getTime($pattern) {
Get-Content $logFile | %{ if ($_.Split('t') -match $pattern) {$_} }
}
getTime("code")
дает мне
simple 17-Feb-2011 10:45:27 Updating source code to revision: 49285
simple 17-Feb-2011 10:54:22 Updated source code to revision: 49285
но если я изменю значение печати с
$_
Для
$matches
Я ничего не получаю. Я думал, что этот массив должен был быть создан автоматически? возможно, это что-то глупое, но это мой первый день использования powershell 🙂
РЕДАКТИРОВАТЬ: то, что я хочу вернуть, это
Get-Date (column 2 of the matching line)
Ответ №1:
Ваш вызов к Split()
использует соглашения C #, чтобы избежать t
указания символа табуляции. В PowerShell вы используете один обратный переход, например, $_.Split("`t")
. Также -match
он ведет себя немного по-другому в массиве, подобном этому, поэтому пусть он работает с каждой отдельной строкой следующим образом:
Get-Content $logFile | Foreach {$_.Split("`t")} | Where { $_ -match $pattern }
Здесь также есть своего рода скрытый трюк с Get-Content, где вы можете заставить его разделить для вас:
Get-Content $logFile -del "`t" | Where { $_ -match $pattern }
Обновление: на основе обновленного вопроса попробуйте что-то вроде этого:
gc $logFile | % {$cols = $_.Split("`t"); if ($cols[2] -match $pattern) {$cols[1]}}
Имейте в виду, что массивы в PowerShell основаны на 0. Если текст уже находится в формате DateTime, понятном для PowerShell / .NET, вы можете просто преобразовать его в DateTime вот так [DateTime]$cols[1]
.
Комментарии:
1. спасибо за ответ! проблема в том, что мой вопрос, вероятно, был неправильным 🙂 У меня есть строки, состоящие из 3 столбцов, шаблон $ соответствует третьему столбцу, но я хочу вернуть Get-Date второго столбца этой строки. Как мне это сделать?
Ответ №2:
$_.Split('t')
Это нарушает его.
Во-первых, он прерывается на каждой букве «t», а не на вкладках. Во-вторых, он возвращает массив, который сбивает с толку -match
.
С помощью следующего кода:
Get-Content $logFile | %{ if ($_ -match $pattern) { $matches } }
getTime("code")
вернул бы:
Name Value
---- -----
0 code
0 code
Это позволило бы выполнять поиск с помощью регулярных выражений, как в
$answerArray = getTime("(t)(d )")
$digitsOfSecondResult = $answerArray[1][2]
Write-Output $digitsOfSecondResult
Если вы просто хотите напечатать строки, соответствующие шаблону, попробуйте:
Get-Content $logFile | %{ if ($_ -match $pattern) { $_} }
Чтобы получить дату:
function getTime($pattern) {
Get-Content $logFile | %{ if ($_ -match $pattern) { Get-Date $matches[1] } }
}
getTime("`t(. )`t.*code")
Или:
function getTime($pattern) {
Get-Content $logFile | %{ if ($_ -match "`t(. )`t.*$pattern") { Get-Date $matches[1] } }
}
getTime("code")
Комментарии:
1. @seminolas Get-Date $соответствует[1], если $pattern равен »
t(. )
t.*code», возвращает поле даты строк, содержащих слово «code» в третьем поле. (`t означает вкладку).