PDA

Показать полную графическую версию : [решено] Обработка текстового лога


GOLDLION
25-05-2011, 20:57
Здравствуйте.
Есть потребность в обработчике текстовых лог-файлов вида 1_Errors.log, 2_Errors.log и т.д.. В файлах записи такого рода:
-------------------------------------------------------------------------------
11.05.2011 15:21:39 : ERROR_FILE_NOT_FOUND
-------------------------------------------------------------------------------
11.05.2011 15:21:39 : Не найден файл D:\Backgrounds\low_Regbi2_3_00_10.05.11_SportReportTV.mpg
-------------------------------------------------------------------------------
11.05.2011 16:10:05 : Тайм-аут канала запроса во время ожидания ответа после истечения 00:00:03.7968750. Увеличьте значение времени тайм-аута, передаваемое вызову при Request или увеличьте значение SendTimeout в Binding. Время, назначенное для выполнения этой операции, может быть составной частью более длинного тайм-аута.
-------------------------------------------------------------------------------
11.05.2011 16:10:19 : Тайм-аут канала запроса при попытке отправить после истечения 00:00:04. Увеличьте значение времени тайм-аута, передаваемое вызову при Request или увеличьте значение SendTimeout в Binding. Время, назначенное для выполнения этой операции, может быть составной частью более длинного тайм-аута.
-------------------------------------------------------------------------------
11.05.2011 15:55:17 : Не удалось подключиться к http://***/***.WCFService/Service.svc. Код ошибки TCP 10065: Сделана попытка выполнить операцию на сокете для недоступного хоста ***.
-------------------------------------------------------------------------------
24.05.2011 01:34:27 : Не удалось подключиться к http://***/***.WCFService/Service.svc. Код ошибки TCP 10065: Сделана попытка выполнить операцию на сокете для недоступного хоста ***.

Интересует выбор последних по дате(наиболее новых) записей, удаление остальных, после этого удаление всех строк, кроме строк вида
11.05.2011 15:21:39 : Не найден файл D:\Backgrounds\low_Regbi2_3_00_10.05.11_SportReportTV.mpg
После удалить во всех строках все символы от начала строки до D:\ .
Результатом должен быть текстовый файл, в котором в каждой строке будет запись вида D:\Backgrounds\low_Regbi2_3_00_10.05.11_SportReportTV.mpg

По аналогии с http://forum.oszone.net/thread-187189-2.html не получилось.(не получается правильно задать переменную вроде бы)
Если делать так: type *.log | findstr /i /o "mpg" > temp1.txt
получатся что-то похожее:
443:11.05.2011 15:21:39 : Не найден файл D:\Backgrounds\low_Regbi2_3_00_10.05.11_SportReportTV.mpg, но не знаю как отсортировать последние и отделить путь D:\Backgrounds\* от мусора.

amel27
26-05-2011, 05:14
GOLDLION, фильтровать логичней по тексту искомой ошибки,
только надо следить, чтобы кодировка текста в логах и батнике была одинаковой.
@Echo Off
SetLocal EnableDelayedExpansion
::-----------------------
Set "TXT=Не найден файл "
::-----------------------
Type Nul >temp1.txt
For /F %%d In ('DIR/B/OD *.log') Do Find "%TXT%"<"%%d">>temp1.txt
For /F "UseBackQ" %%a In ("temp1.txt") Do Set "KEY=%%a"
(For /F "UseBackQ Tokens=1*" %%a In ("temp1.txt") Do (Set "$b=%%b"
If "%%a"=="%KEY%" Echo !$b:*%TXT%=!
))>temp2.txt

GOLDLION
30-05-2011, 11:40
amel27, спасибо!!! Работает именно так, как нужно.
Не сочтите за наглость, просто не совсем понимаю, как батник работает.

SetLocal EnableDelayedExpansion » - включаем расширеную обработку команд. Для чего именно? Переменную TXT можно корректно задать и без этого.

Type Nul >temp1.txt » - выводим пустые строки в файл temp1.txt

For /F %%d In ('DIR/B/OD *.log') Do Find "%TXT%"<"%%d">>temp1.txt » - для отсортированого файла с расширением .log выбирается последний по дате изменения файл,
в нем ищется текст, заданный переменной TXT, и все записи, содержащие этот текст помещаются в текстовый файл temp1.txt.

Далее не могу понять, как именно работает конструкция For c с вложенной For. Т.е. имеено та самая "очистка от мусора".

amel27
30-05-2011, 13:05
включаем расширеную обработку команд. Для чего именно? »нет, это отложенное расширение переменных (через знак "!"), используется в команде ECHO последнего цикла для вывода значения переменной $b, для справки смотрите "CMD /?"
выводим пустые строки в файл temp1.txt »нет, зачищаем содержимое файла temp1.txt, хотя можно просто удалить через DEL
для отсортированого файла с расширением .log выбирается последний по дате изменения файл »нет, содержимое каждого LOG-файла с текстом "%TXT%" выводится в temp1.txt... В результате мы получаем один файл со всеми ошибками, отсортированными по дате, значит, дата последней строки будет искомой, её и читаем в переменную KEY в следующей команде:
For /F "UseBackQ" %%a In ("temp1.txt") Do Set "KEY=%%a"Осталось построчно прочитать файл, отобрать строки с датой =="%KEY%" и сохранить их в другом файле, но уже без левой ненужной части, это и делает последний цикл. %%a равно дате (первый токен), %%b - вся остальная часть строки, которую предварительно сохраняем в переменную $b, а подстановка !$b:*%TXT%=! заменяет в переменной $b "%TXT%" и всё что слева на пустую строку (т.е. удаляет).

P.S. кстати, тут нет вложенных FOR

GOLDLION
30-05-2011, 18:40
Теперь понятней, но повторить в другой задаче скорее всего не смогу :(
Разве что какую-то часть.
А как правильно назвать вот то предварительное сохранение в $b?
DIR/B/OD сортирует все *.log и результатом будут только имена файлов(/В) начиная со старых(/OD). Это делается, для того, чтобы получился список с отсортированными строками, в которых найдено совпадение с "%TXT%", и именно последняя была самой новой? Без DIR/B/OD »
получилась бы "каша" ведь?
И еще: если бы нужно было заменить не все что слева, а все что справа, как бы выглядела подстановка !$b:*%TXT%=! »?

amel27
31-05-2011, 08:43
А как правильно назвать вот то предварительное сохранение в $b? »присвоение переменной $b значения текущей строки файла (без 1-го токена - даты): SET "$b=%%b"
DIR/B/OD сортирует все *.log и результатом будут только имена файлов(/В) начиная со старых(/OD). Это делается, для того, чтобы получился список с отсортированными строками, в которых найдено совпадение с "%TXT%", и именно последняя была самой новой? »именно так :)
Без
DIR/B/OD »
получилась бы "каша" ведь?»необязательно, по умолчанию DIR сортирует по имени, при соответствующем правиле именования файлов результат обеих сортировок может быть одинаков
если бы нужно было заменить не все что слева, а все что справа »к сожалению, такой команды нет, приходится в каждом конкретном случае выкручиваться (

GOLDLION
01-06-2011, 19:29
... при обработке могут дублироваться строки, причем идентичны они только в temp2.txt
Как удалить дублирующиеся строки с выводом уникальных в temp3.txt? Нашел такую конструкцию
setlocal
cd.>1.tmp
set /p str=<1.txt
:loop
1>>1.tmp (echo %str%)
for /f "tokens=*" %%i in ('findstr /v /g:1.tmp 1.txt') do set "str=%%i" && goto:loop
move 1.tmp 1.txt , но не полу
но, это не работает.
Тут http://forum.oszone.net/thread-187668.html показано как, но... опять же не понимаю как работает :(
И там же по маске, а тут именно дублирующиеся.
Кстати, можно ли в файле temp2.txt в виде комментария подписывать из какого именно *_Errors.log вытянута строка или блок строк?

amel27
02-06-2011, 08:43
Как удалить дублирующиеся строки с выводом уникальных в temp3.txt? Нашел такую конструкцию »по ряду причин FINDSTR не лучшее решение для этой задачи:

1. Формат файла шаблона отличается от обычного текста - например, символ "\" должен экранироваться в шаблоне "\\".
2. FINDSTR не работает с длинными шаблонами, выдавая ошибки на превышение длины или нехватку памяти.
3. Вложенный цикл будет очень медленным для больших файлов.

п.1 можно учесть в батнике (1.txt -> 2.txt):@echo off
SetLocal EnableDelayedExpansion

echo \\>"1.tmp"
(for /f "usebackq" %%i in ("1.txt") do (set "$a="
for /f "delims=" %%a in ('findstr/ixvg:"1.tmp" 1.txt') do (
if not defined $a (set "$a=%%a"
echo/!$a!
set "$a=!$a:\=\\!"
set "$a=!$a:.=\.!"
echo/!$a!>>"1.tmp"
))))>"2.txt"
альтернативный вариант - предварительная сортировка с обычным циклом:@echo off
SetLocal EnableDelayedExpansion

sort /l "C" "1.txt" /o "1.tmp"
(for /f "usebackq delims=" %%a in ("1.tmp") do (
if /i not "%%a"=="!$a!" echo/%%a
set "$a=%%a"
))>1.txt
можно ли в файле temp2.txt в виде комментария подписывать из какого именно *_Errors.log вытянута строка или блок строк? »как-то не вяжется с задачей удаления дублей - где подписывать и какой из логов оставлять при дублях?

GOLDLION
02-06-2011, 13:04
В общем случае, вся эта обработка нужна для того, чтобы определить, какие файлы не скопировались с фтп из-за отсутствия интернета на объекте и скопировать их вручную с флешки. Файлы в основном по 160-200 Мб/шт, и если на 14 ПК не хватает 1-5 файлов, а на одном, например, 30, то сливать на каждом объекте по 6 гиг будет относительно долго, а этот один визуально сразу будет видно(первый символ файлов Errors - это код объекта) и можно сэкономить время.
Если делать вывод в temp2 без удаления дублирующихся, но делать комментарии из какого лога вытянуто, то получится отчет пообъектно. Если потом в temp2 удалить дублирующиеся(коментарии тут уже не нужны)строки, то выйдет сводный отчет, который выводится в temp3.

amel27
02-06-2011, 14:20
@Echo Off
SetLocal EnableDelayedExpansion
::-----------------------
Set "TXT=Не найден файл "
::-----------------------
Set/A "ln=0,li=0"
(For /F "Delims=" %%a In ('DIR/B/OD *.log') Do (
For /F "Tokens=1*" %%b In ('Find "%TXT%"^<"%%a"') Do (
If Not "%%b"=="!$b!" Set "ln=!li!"& Set "$b=%%b"
Set "$c=%%c"& Set/A li+=2
Echo ;%%a
Echo !$c:*%TXT%=!
)))>temp1.txt

More +%ln% temp1.txt >temp2.txt
Sort /L "C" "temp2.txt" /O "temp2.tmp"

(For /F "UseBackQ Delims=" %%a In ("temp2.tmp") Do (
If /I Not "%%a"=="!$a!" Echo %%a
Set "$a=%%a"
))>"temp3.txt"

GOLDLION
02-06-2011, 17:05
Рэспект! То,что нужно.




© OSzone.net 2001-2012