регулярные выражения powershell

#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 означает вкладку).