Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Обработка текстового лога (http://forum.oszone.net/showthread.php?t=207571)

GOLDLION 25-05-2011 20:57 1682551

Обработка текстового лога
 
Здравствуйте.
Есть потребность в обработчике текстовых лог-файлов вида 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 1682734

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 1684988

amel27, спасибо!!! Работает именно так, как нужно.
Не сочтите за наглость, просто не совсем понимаю, как батник работает.

Цитата:

Цитата amel27
SetLocal EnableDelayedExpansion »

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

Цитата:

Цитата amel27
Type Nul >temp1.txt »

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

Цитата:

Цитата amel27
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 1685048

Цитата:

Цитата GOLDLION
включаем расширеную обработку команд. Для чего именно? »

нет, это отложенное расширение переменных (через знак "!"), используется в команде ECHO последнего цикла для вывода значения переменной $b, для справки смотрите "CMD /?"
Цитата:

Цитата GOLDLION
выводим пустые строки в файл temp1.txt »

нет, зачищаем содержимое файла temp1.txt, хотя можно просто удалить через DEL
Цитата:

Цитата GOLDLION
для отсортированого файла с расширением .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 1685237

Теперь понятней, но повторить в другой задаче скорее всего не смогу :(
Разве что какую-то часть.
А как правильно назвать вот то предварительное сохранение в $b?
DIR/B/OD сортирует все *.log и результатом будут только имена файлов(/В) начиная со старых(/OD). Это делается, для того, чтобы получился список с отсортированными строками, в которых найдено совпадение с "%TXT%", и именно последняя была самой новой? Без
Цитата:

Цитата amel27
DIR/B/OD »

получилась бы "каша" ведь?
И еще: если бы нужно было заменить не все что слева, а все что справа, как бы выглядела подстановка
Цитата:

Цитата amel27
!$b:*%TXT%=! »

?

amel27 31-05-2011 08:43 1685470

Цитата:

Цитата GOLDLION
А как правильно назвать вот то предварительное сохранение в $b? »

присвоение переменной $b значения текущей строки файла (без 1-го токена - даты): SET "$b=%%b"
Цитата:

Цитата GOLDLION
DIR/B/OD сортирует все *.log и результатом будут только имена файлов(/В) начиная со старых(/OD). Это делается, для того, чтобы получился список с отсортированными строками, в которых найдено совпадение с "%TXT%", и именно последняя была самой новой? »

именно так :)
Цитата:

Цитата GOLDLION
Без
DIR/B/OD »
получилась бы "каша" ведь?»

необязательно, по умолчанию DIR сортирует по имени, при соответствующем правиле именования файлов результат обеих сортировок может быть одинаков
Цитата:

Цитата GOLDLION
если бы нужно было заменить не все что слева, а все что справа »

к сожалению, такой команды нет, приходится в каждом конкретном случае выкручиваться (

GOLDLION 01-06-2011 19:29 1686608

... при обработке могут дублироваться строки, причем идентичны они только в 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 1686879

Цитата:

Цитата GOLDLION
Как удалить дублирующиеся строки с выводом уникальных в 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


Цитата:

Цитата GOLDLION
можно ли в файле temp2.txt в виде комментария подписывать из какого именно *_Errors.log вытянута строка или блок строк? »

как-то не вяжется с задачей удаления дублей - где подписывать и какой из логов оставлять при дублях?

GOLDLION 02-06-2011 13:04 1687031

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

amel27 02-06-2011 14:20 1687071

Код:

@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 1687187

Рэспект! То,что нужно.


Время: 17:54.

Время: 17:54.
© OSzone.net 2001-