2014-01-16 2 views
1

Мой первый вопрос здесь, и просто хочу сказать спасибо за все те материалы, которые я получил за эти годы с этого сайта.Get-Content - получить весь контент, начиная с определенного linenumber

Я также новичок в powershell, поэтому ансвар может быть очень простым.

Я работаю над скриптом, который проверяет файл журнала каждые 5 минут. (запланировано из ActiveBatch).

В настоящий момент скрипт ищет ERROR в файле журнала. И он отлично работает. Но моя проблема заключается в том, что скрипт выполняет поиск всего файла каждый раз. Поэтому, когда ERROR действительно происходит, проверка «терпит неудачу» каждые 5 минут до конца дня. Пока не будет создан новый файл журнала.

Мой сценарий:

Write-Host Opretter variabler... 
$file = "${file}" 
$errorString = "${errorString}" 
Write-Host file variable is: $file 
Write-Host errorString variable is: $errorString 
Write-Host 
Write-Host Select String Results: 
$ssResult = Get-Content $file | Select-String $errorString -SimpleMatch 
Write-Host 
Write-Host There was $ssResult.Count `"$errorString`" statements found... 
Write-Host 
IF ($ssResult.Count -gt 0) {Exit $ssResult.Count} 

Так что я хотел бы, чтобы найти ошибку, а затем Remeber в LINENUMBER (Возможно, в файле). Затем в следующем прогоне (5 минут позже) я хочу начать поиск с этой строки.

например. И ошибка найдена в строке 142, сценарий выходит с кодом ошибки 142. Пять минут спустя сценарий запускается снова, и он должен начинаться с строки 143 и проходить через остальную часть файла.

ответ

1

Можно вспомнить количество строк ошибок, обнаруженных в файле:

$ssResult.Count > C:\path\to\file.txt 

Тогда число нового erros является:

$errorCount = $ssResult.Count - (Get-Content C:\path\to\file.txt) 

Не забудьте установить значение в файле к нулю при первом запуске сценария и каждый раз, когда генерируется новый файл журнала.

+0

Привет Дан Спасибо за ваш вклад, хорошего и простого, и я думаю, что он будет работать нормально. Я отдам его. –

1

Вы в основном дали довольно хорошее описание того, как он будет работать:

  1. Прочитайте последний номер строки

    $if (Test-Path $Env:TEMP\last-line-number.txt) { 
        [int]$LastLineNumber = @(Get-Content $Env:TEMP\last-line-number.txt)[0] 
    } else { 
        $LastLineNumber = 0 
    } 
    
  2. Прочитайте файл

    $contents = Get-Content $file 
    
  3. Найдите первая ошибка, начинающаяся с $LastLineNumber (один из редких случаев s, где for уместно в PowerShell, чтобы мы не хотим, чтобы создать более хорошие объекты)

    for ($i = $LastLineNumber; $i -lt $contents.Count; $i++) { 
        if ($contents[$i] -like "*$errorString*") { 
        $i + 1 > $Env:TEMP\last-line-number.txt 
        exit ($i + 1) 
        } 
    } 
    
+0

В чем преимущество 'for' loop over' $ content | выберите -Skip $ LastLineNumber | ? {$ _ -like "* $ errorString *"} '? Кроме того, начальное значение '$ LastLineNumber' должно быть 0, а' + (Get-Content ...) 'не работает в PowerShell до версии v3. –

+0

Я понял их, что им нужна только первая ошибка (и выйдите со своим номером строки). У этого есть различные проблемы, конечно, один из них - то, что более чем одна ошибка каждые пять минут является проблематичной. Обычно я никогда не пишу цикл 'for' или' foreach', если это не полезно при игре в гольф. Я бы, вероятно, подошел к проблеме по-другому, если бы это был мой собственный. – Joey

+0

Привет, Джо, спасибо за ввод, но я думаю, что поеду за советом Дано;) –

1

Select-String Возвращает MatchInfo объекты, которые имеют номер строки, так что вы можете должны быть в состоянии сделать что-то подобное :

$lasterror = Get-Content $lasterrorfile 

$newerrors = select-string -Path $file -Pattern $errorstring -SimpleMatch | 
where $_.LineNumber -gt $lasterror 

Write-Host "$($newerrors.count) found." 

if ($newerrors.count) 
{$newerrors[-1].LineNumber | Set-Content $lasterrorfile} 
+0

Hi mjolinor Спасибо за ваш вклад, я думаю, что именно этот ответ я просил. Спасибо вам за это. Но мне нравится простота ответа Дано, и я попытаюсь это сделать первым :) Я дам вам, ребята, знать, как это работает –

1

Так что это мой последний сценарий, спасибо Дано. Я уверен, что день-Reset, что можно сделать умнее, но это, кажется, работает :)

#logic for Day-Reset 
Write-Host checking if its a new day... 
$today = Get-Date -format dddd 
$yesterday = Get-Content $ENV:TEMP\${adapterName}_yesterday.txt 
Write-Host today variable is: $today 
Write-Host yesterday variable is: $yesterday 
Write-Host 

IF ($today.CompareTo($yesterday)) 
    { 
     Get-Date -format dddd > $ENV:TEMP\${adapterName}_yesterday.txt 
     0 > $ENV:TEMP\${adapterName}_numberofErrors.txt 
    } 


Write-Host Setting variables... 
$file = "${file}" 
$errorString = "${errorString}" 
Write-Host file variable is: $file 
Write-Host errorString variable is: $errorString 
Write-Host 
Write-Host Select String Results: 
$ssResult = Get-Content $file | Select-String $errorString -SimpleMatch 
Write-Host There was $ssResult.Count `"$errorString`" statements found... 
$errorCount = $ssResult.Count - (Get-Content $ENV:TEMP\${adapterName}_numberofErrors.txt) 
Write-Host There was $errorCount new `"$errorString`" statements found... 
Write-Host 
$ssResult.Count > $Env:TEMP\FXAll_numberofErrors.txt 
Exit $errorCount 
Смежные вопросы