Форум программистов, компьютерный форум, киберфорум
Наши страницы
Batch (CMD/BAT)
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.82
surer
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 13
#1

Парсер лога - CMD/BAT

08.10.2012, 10:33. Просмотров 1584. Ответов 14
Метки нет (Все метки)

Доброе утро!

Подскажите, пожалуйста, как можно с помощью CMD распарсить лог вида:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
TN   008 0 00 01 
TYPE 3905
CDEN 8D
CTYP XDLC
CUST 0 
MRT  
ERL  0 
FDN  
TGAR 0 
LDN  NO
NCOS 1 
SGRP 0 
RNPG 0 
SCI  0 
SSU  
LNRS 16 
XLST 2 
SFLT NO
CAC_CIS 3 
CAC_MFC 0
Командой findstr(findstr /b /g:stroki.txt original.log >parsed.txt) нахожу строки, начинающиеся с необходимых мне.
Получается что-то вида (строки повторяются, так как они содержатся в каждом блоке, а их больше 1000):
Bash
1
2
3
4
5
6
7
8
9
10
11
12
CTYP XDLC
NCOS 1 
SGRP 0 
RNPG 0
CTYP XDLC
NCOS 2 
SGRP 0 
RNPG 1
CTYP XDLC
NCOS 3 
SGRP 0 
RNPG 0
Так вот задача в том, чтоб на выходе получились только значения (разделитель точка с запятой, запятая или табуляция, не суть), причем 1 блок = 1 строка.
Для данного примера должно быть так:
Bash
1
2
3
XDLC;1;0;0
XDLC;2;0;1
XDLC;3;0;0
В чем сложность? В том, что в некоторых блоках значения пустые или такой строки вообще нет. Тогда должно быть что-то вроде:
Bash
1
2
3
XDLC;1;;0
XDLC;2;0;1
XDLC;3;0;0
для того, чтобы не терялся столбец в том же Excel

Заранее благодарен за помощь
http://www.cyberforum.ru/cmd-bat/thread372627.html
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.10.2012, 10:33
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Парсер лога (CMD/BAT):

PSexec, запись лога с условием
Всем привет , есть такая внештатная ситуация Нужно проверить на подсети ip...

Убрать скобки при парсинге лога
Возникла необходимость написать очередной парсер :) Есть файл-лог (например,...

Проверка наличия каталогов и ведение лога
При помощи цикла For написать командный файл, который: после запуска...

Батник для разбора лога (фильтрации текста)
Здравствуйте, форумчане! Я - новичек и на форуме и в программировании тоже,...

Создание лога только в случае существования директории
Здравствуйте не подправите код он создает файл log.txt в любом случаи если...

14
Somebody
2799 / 1610 / 251
Регистрация: 03.12.2007
Сообщений: 4,211
Завершенные тесты: 3
08.10.2012, 14:19 #2
Лучший ответ Сообщение было отмечено как решение

Решение

CTYP или какое-то первое значение всегда есть? Или как определять, где следующий блок? В общем типа такого:
Код
setlocal enableextensions enabledelayedexpansion

set nKeys=4
set keyNames[0]=CTYP
set keyNames[1]=NCOS
set keyNames[2]=SGRP
set keyNames[3]=RNPG
set input=in.txt
set output=out.txt

set /a lastKeyIndex=nKeys-1

del %output%
call :EraseKeys
for /f "tokens=1,*" %%a in (%input%) do (
  set aa=%%a
  if %%a==%keyNames[0]% if not x!key%keyNames[0]%!==x (
    call :Flush
	call :EraseKeys
  )
  set key%%a=%%b
)
call :Flush
endlocal
exit /b

:EraseKeys
for /l %%i in (1, 1, %lastKeyIndex%) do set key!keyNames[%%i]!=
exit /b

:Flush
for /f %%t in ("key!KeyNames[0]!") do set str=!%%t!
for /l %%i in (1, 1, %lastKeyIndex%) do (
  for /f %%t in ("key!KeyNames[%%i]!") do set str=!str!;!%%t!
)
echo %str% >>%output%
exit /b
0
surer
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 13
08.10.2012, 15:30  [ТС] #3
Да, первое значение постоянно и является началом следующего блока.
Вот что получилось:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
D:\sur\333>setlocal enableextensions enabledelayedexpansion
 
D:\sur\333>set nKeys=7
 
D:\sur\333>set keyNames[0]=TN
 
D:\sur\333>set keyNames[1]=TYPE
 
D:\sur\333>set keyNames[2]=AST
 
D:\sur\333>set keyNames[3]=IAPG
 
D:\sur\333>set keyNames[4]=KEY  00
 
D:\sur\333>set keyNames[5]=     01
 
D:\sur\333>set keyNames[6]=     02
 
D:\sur\333>set input=putty_full.log
 
D:\sur\333>set output=out.txt
 
D:\sur\333>set /a lastKeyIndex=nKeys-1
 
D:\sur\333>del out.txt
Не удается найти D:\sur\333\out.txt
 
D:\sur\333>call :EraseKeys
 
D:\sur\333>for /L %i in (1 1 6) do set key!keyNames[%i]!=
 
D:\sur\333>set key!keyNames[1]!=
 
D:\sur\333>set key!keyNames[2]!=
 
D:\sur\333>set key!keyNames[3]!=
 
D:\sur\333>set key!keyNames[4]!=
 
D:\sur\333>set key!keyNames[5]!=
 
D:\sur\333>set key!keyNames[6]!=
 
D:\sur\333>exit /b
Непредвиденное появление: !==x.
 
D:\sur\333>  if %a==TN    if not x!keyTN   !==x (
0
Dragokas
Эксперт WindowsАвтор FAQ
16922 / 7007 / 851
Регистрация: 25.12.2011
Сообщений: 10,803
Записей в блоге: 16
08.10.2012, 16:44 #4
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@echo off
setlocal EnableDelayedExpansion
::Имя исходного файла
set orig=original.log
::Имя файла с подстановочными словами
set maskfile=stroki.txt
::Имя результирующего файла со значениями
set result=result.log
::Количество значений на строку
set /a nmax=4
 
if exist %result% del /f /q %result%
 
for /f "tokens=1-2*" %%a in ('findstr /b /g:%maskfile% %orig%') do (
  set /a n+=1
  set stri=!stri!%%b;
  if !n!==%nmax% (
    echo !stri:~0,-1!>>%result%
    set /a n=0
    (set stri=) 
  )
)
if n NEQ 0 echo !stri:~0,-1!>>%result%
pause>nul
1
surer
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 13
08.10.2012, 18:10  [ТС] #5
Работает! Но не так, как хотелось бы.
Слишком много режет.
Bash
1
2
3
4
5
008;3905;00;1
00;SCR;NRD;008
3905;00;1;00
SCR;NRD;008;3905
00;1;00;SCR
Это пример из результата, а должно быть примерно так:
Bash
1
2
3
008 0 00 00 ;3905;00 01 ;1; ACD 2780261 2  36265; SCR 2780265 2     MARP; NRD 
008 0 00 01 ;3905;00 01 ;1; ACD 2780261 2  36267; SCR 2780267 2     MARP; NRD 
008 0 00 02 ;3905;00 01 ;1; ACD 2780261 2  36268; SCR 2780268 2     MARP; NRD
Отсюда вывод: режет до первого пробела. Нужно 7 значений, но где-то их всего 5 или 6, поэтому, если задавать четко 7 значений на строку, то результат уедет, после первого пустого значения.

Поправка: выставил 7 значений, вроде, выставляет пустые, но все же остается проблема, что режет после первого пробела
0
Somebody
2799 / 1610 / 251
Регистрация: 03.12.2007
Сообщений: 4,211
Завершенные тесты: 3
08.10.2012, 18:26 #6
Цитата Сообщение от surer Посмотреть сообщение
Bash
1
2
Непредвиденное появление: !==x.
D:\sur\333>  if %a==TN    if not x!keyTN   !==x (
Видимо, в конце строки set keyNames[0]=TN три пробела, которые тоже попадают в переменную.
Цитата Сообщение от surer Посмотреть сообщение
режет до первого пробела
"tokens=1*"
0
Dragokas
Эксперт WindowsАвтор FAQ
16922 / 7007 / 851
Регистрация: 25.12.2011
Сообщений: 10,803
Записей в блоге: 16
08.10.2012, 21:38 #7
Сделайте аналогично в моей строке № 14.
"tokens=1-2*" поменяйте на "tokens=1*"
0
surer
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 13
08.10.2012, 23:02  [ТС] #8
Цитата Сообщение от Dragokas Посмотреть сообщение
Сделайте аналогично в моей строке № 14.
"tokens=1-2*" поменяйте на "tokens=1*"
Спасибо, помогло. Только вот дальше данные поплыли.
Ситуация такая:
Bash
1
2
3
4
5
6
7
8
9
10
11
DES  SOVINT
TN   008 0 07 00 
TYPE RAN 
CUST 0 
XTRK EXUT
TIMP 600 
BIMP 600 
AUTO_BIMP NO
RTMB 49 1 
CONN 14 
DATE NO DATE
Это в исходнике, то есть в этом блоке всего 2 необходимых строки TN и TYPE. Дальше таких еще десяток блоков. То есть в резалте должно быть следующее:
008 0 07 00;RAN;;;;;
И далее:
Bash
1
2
3
4
5
6
008 0 07 01;MUS;;;;;
008 0 07 02;MUS;;;;;
008 0 07 03;MUS;;;;;
008 0 07 04;MUS;;;;;
008 0 07 05;RAN;;;;;
...
А у меня вышло вот так:
Bash
1
2
3
4
5
008 0 07 00 ;RAN ;008 0 07 01 ;MUS ;008 0 07 02 ;MUS ;008 0 07 03 
MUS ;008 0 07 04 ;MUS ;008 0 07 05 ;RAN ;008 0 07 06 ;MUS 
008 0 07 07 ;MUS ;012 0 00 00 ;MUS ;012 0 00 01 ;MUS ;012 0 00 02 
RAN ;012 0 00 03 ;RAN ;012 0 00 04 ;RAN ;012 0 00 05 ;RAN 
012 0 00 06 ;RAN ;012 0 00 07 ;RAN ;012 0 01 00 ;3905;00 01
Печаль.
0
Dragokas
Эксперт WindowsАвтор FAQ
16922 / 7007 / 851
Регистрация: 25.12.2011
Сообщений: 10,803
Записей в блоге: 16
09.10.2012, 00:27 #9
Так если в строке № 10 выставить число 2, приблизительно такое, как Вы написали, и получится.

Если "всего 2 необходимых строки TN и TYPE", то откуда в планируемом результате взялись пустые значения ;;;;; в кол-ве 5 шт. (почему именно 5) ?
Прикрепите все же сюда полный файл-исходник, а то как-то неясно.
0
surer
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 13
09.10.2012, 09:10  [ТС] #10
В строке должно быть 7 столбцов: TN, TYPE, AST, IAPG, KEY 00, KEY 01, KEY 02. Пустые значения должны подставляться, чтоб не было смещения по столбцам. Сейчас они подставляются только в том случае, если есть строка без параметра, а надо даже при отсутствии самой строки, иначе видим смещение.

Полный лог прикрепил.
0
Вложения
Тип файла: rar putty_full.rar (20.2 Кб, 4 просмотров)
surer
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 13
10.10.2012, 11:35  [ТС] #11
UP
Так близко к решению... Есть идеи?

Печаль
0
Dragokas
Эксперт WindowsАвтор FAQ
16922 / 7007 / 851
Регистрация: 25.12.2011
Сообщений: 10,803
Записей в блоге: 16
16.10.2012, 02:44 #12
surer, а в чем проблема? - первый вариант скрипта Somebody замечательно отрабатывает на файле putty.
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@echo off
setlocal enableextensions enabledelayedexpansion
 
set nKeys=7
set keyNames[0]=TN
set keyNames[1]=TYPE
set keyNames[2]=AST
set keyNames[3]=IAPG
set keyNames[4]=AAA
set keyNames[5]=BBB
set keyNames[6]=CCC
set input=in.txt
set output=out.txt
 
set /a lastKeyIndex=nKeys-1
 
del %output%
call :EraseKeys
for /f "tokens=1,*" %%a in (%input%) do (
  set aa=%%a
  if %%a==%keyNames[0]% if not x!key%keyNames[0]%!==x (
    call :Flush
    call :EraseKeys
  )
  set key%%a=%%b
)
call :Flush
pause
goto :eof
 
:EraseKeys
for /l %%i in (1, 1, %lastKeyIndex%) do set key!keyNames[%%i]!=
exit /b
 
:Flush
for /f %%t in ("key!KeyNames[0]!") do set str=!%%t!
for /l %%i in (1, 1, %lastKeyIndex%) do (
  for /f %%t in ("key!KeyNames[%%i]!") do set str=!str!;!%%t!
)
echo %str% >>%output%
exit /b
0
Вложения
Тип файла: rar out.rar (2.2 Кб, 6 просмотров)
surer
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 13
16.10.2012, 10:33  [ТС] #13
Последние 3 ключа не цепляются. В них есть пробелы.
0
Dragokas
Эксперт WindowsАвтор FAQ
16922 / 7007 / 851
Регистрация: 25.12.2011
Сообщений: 10,803
Записей в блоге: 16
16.10.2012, 10:39 #14
Да, не будут цепляться. И вряд ли легко получится сделать.
Есть вариант сделать сначала предобработку списка (например, заменить ключи с пробелами - пробелы на знак подчеркивания (сейчас можете даже поэкспериментировать с простым блокнотом). Повторить выполнение скрипта, указав ключи KEY_00, KEY_01, KEY_02.

Алгоритм работы моего из 4-го поста совсем неверный, поэтому здесь он будет бесполезен.
1
surer
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 13
16.10.2012, 10:42  [ТС] #15
Ну как вариант, кстати! Только вот в блокноте замена может занять годы
Тот же WordPad быстрее. Спасибо за совет!
0
16.10.2012, 10:42
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.10.2012, 10:42
Привет! Вот еще темы с решениями:

Можно ли к определённому тексту из лога батника привязать задачу?
Может не совсем правильно описал, но вопрос следующий. Допустим надо отправить...

Определение буквы диска по его номеру из лога, создаваемого DiskPart
Лог diskpart: Microsoft DiskPart version 6.1.7601 Copyright (C) 1999-2008...

Создание лога копирования файлов: что, куда и сколько времени на это ушло
Привет ВСЕМ может кто знает есть ли возможность при копировании вести лог не...

Выборка файлов по расширению, упаковка, отправка адресатам, ведение лога, резервное копирование
Всем привет Сделал следующий батник Он ищет в папке файлы aaa0000bbb*.CNG,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru