2013-06-21 3 views
2

Я пытаюсь найти шаблон «Ошибка» в серии лог-файлов, а затем записывать результаты в текстовый файл.PowerShell: поиск части строки в файле журнала

Я использую команду:

foreach($file in $files){ 

    $match = get-content $file | Select-String $p | Out-File $matchfile 
} 

Узор $ р было принято из командной строки. Я запускаю сценарий в Windows Server 2008 R2 и возвращает результаты, если «Ошибка» - это одно слово в файле журнала. У меня есть экземпляры «ErrorCode», которые я хотел бы, чтобы сценарий идентифицировал.

У меня есть код, работающий на Windows 7, как я бы хотел. Однако я не получаю никаких результатов при запуске скрипта на Windows Server 2008 R2. Обе версии PowerShell 2.0.

+0

Образец '' Ошибка "' должен совпадать как с Error, так и с ErrorCode. Что именно используется в шаблоне? – zdan

ответ

2

Действительно ли вы работаете на Windows 7? Они, как вы его написали, каждая итерация цикла foreach перезаписывает файл match с результатами из последнего файла в $ файлах. Вы можете добавить переключатель -Append после Out-File, но вам даже не нужен цикл foreach. Кроме того, какова цель $ match? $match = выглядит излишним для меня. Попробуйте это:

Get-Content $files | Select-String $p | Out-File $matchfile 

Я подозреваю, что причина, вы не получаете никаких результатов на сервере 2K8 является то, что последний файл в $ файлах не имеет аналогов на $ р. На компьютере с Windows 7 вы получаете результаты, потому что последний файл имеет совпадения для $ p, но вы не получаете результатов от каких-либо других файлов.

+0

Причина, по которой я думал, что она работает с Windows 7, состоит в том, что последний файл журнала содержит шаблон. Ясно, что это было неправильно, и я немного замедлился, и вы совершенно правы, что было проблемой! Большое спасибо! :) – user2509413

0

I second @Adi, вы переписываете файл на каждой итерации. Вы можете решить эту проблему, добавив переключатель Append в значение Out-File. Это также должно работать и прост в использовании:

$files | Select-String $p | Out-File $matchfiles 
0

Я ожидаю, что $ match всегда будет null. Согласно справке, Out-File никогда ничего не отправляет по трубопроводу. Но я был бы удивлен, если бы это было связано с вашей проблемой.


В духе «Любая помощь будет принята с благодарностью» ...

Я попробовал простой эксперимент как на Win7 и WS08R2 и не могли Репрографический результаты (он работал, как и ожидалось). Я также попытался создать поиск файла с различными кодировками: Unicode, UTF8 и ASCII. Все работало. Я даже сказал Select-String использовать неправильную кодировку:

get-content mytestfile.ascii | select-string error -Encoding Unicode 

и все еще работал. Я использовал шестнадцатеричный просмотрщик для проверки того, что mytestfile.ascii, mytestfile.unicode и mytestfile.utf8 были на самом деле закодированы по-разному. Я также пробовал разные окончания строк (стиль Linux и стиль Windows), и это сработало.

Я предполагаю, что у вас есть что-то уникальное в отношении файлов, системы и т. Д., Которые должны быть обнаружены с помощью некоторого зондирования. Имея это в виде ...


Я предлагаю вам заглянуть внутрь одного из ваших логов с шестигранным зрителем (попробуйте его с обоего систем), чтобы увидеть, если что-то отличается от вашей системы Win7 и системы WS08R2. В начале файла UTF8 вы увидите EF BB BF, а затем один байт для каждого символа вашего журнала. В начале файла Unicode вы увидите FF FE, а затем два байта для каждого символа. (Если текст является английским, то каждый другой символ будет 0).А для файла ASCII в начале нет специального значения, и для каждой буквы есть один байт. Окончания строк в Linux - это один вывод 0A (linefeed) и окончания строки Windows: 0D 0A (возврат каретки, перевод строки). Помимо специальных символов в начале, как упоминалось выше, и окончаний строк, вы должны искать текст точно таким же набором символов, как если бы вы просмотрели его в блокноте. (Кстати, просмотр его в блокноте будет выглядеть только «правильно», если окончание строк - это стиль Windows). Если вы видите какие-то дополнительные символы, то это может быть источником проблемы

Если это ничего не показывает, я предлагаю серию экспериментов из командной строки Powershell. Следующая процедура содержит много шагов, но она пытается покрыть множество непредвиденных ситуаций. Вы не будете выполнять каждый шаг. (Однако с несколькими модификациями в начале - для учета того, где «ошибка» появляется в файле журнала, который вы используете для тестирования, - вы можете скопировать и вставить весь этот скрипт, а затем интерпретировать весь набор результатов за один раз)

# 0. Get some text to experiment with 
# If "error" appears on line 200 and line 493 (where first line in file is Line 1), then: 
$testTxt= cat mylogfile | select-object -skip 195 -first 300 
# or better still: 
$testTxt= cat mylogfile | select-object -skip 195 -first 10 
$testTxt2= cat mylogfile | select-object -skip 488 -first 10 
$testTxt += $testTxt 

# 1. Figure out where in testTxt "error" appears 
$testTxt[3..5] # if my math is right "error" will appear as middle line 

# 2. If #1 doesn't work on both systems, then on failing system(s): 
$testTxt[4] | select-string error 

# 2.5 If #2 fails then you need to look at every character 
# of $testTxt 
[char[]]$testTxt 
# or even look at every byte value in hex: 
[byte[]][char[]]$textTxt | % { $_.tostring("X")} 

# 3. If #2 worked, then: 
$testTxt | select-string error 

# 4. If #3 failed, then: 
$testTxt[3..5] | select-string error 

# 5. If #4 failed, then: 
$testTxt[3..4] | select-string error 
$testTxt[4..5] | select-string error 

# 6. If either of #5 failed, then carefully examine those lines of text: 
"line 3" 
[char[]]$testTxt[3] 
"line 4" 
[char[]]$testTxt[4] 
"line 5" 
[char[]]$testTxt[5] 

# 7. If #3 worked then: 
$testTxt2 = cat myLogFile 
$testTxt2 | select-string error 

# 8. If #7 worked, then you have a solution 
# Replace: 
get-content $file | Select-String $p | Out-File $matchfile 
# With (on Powershell v3 this may perform worse than the above, assuming above worked) 
$logText = get-content $file 
$logText | Select-String $p | Out-File $matchfile 

# 9. If #8 failed, then the situation is somewhat awkward. 
# On one hand you have twenty lines working, but on the other the file as a whole 
# doesn't work. You could go back to step #0 and start with a larger amount of text, 
# say 40 lines, and see if it works. If it does you could try 80, 160, etc. until it 
# fails. But this case seems pretty unlikely. 

# 10. In general when a step fails you want to try something "smaller". And when steps 
#  succeed you want to try something "bigger", where "bigger" means more like the 
#  solution you want.