如果重复一个字符串,试图找出一种方法让批处理从日志文件返回一行。该字符串包含时间戳,因此字符串会更改。
我做了一个示例日志。 我希望在同一秒内在时间戳字符串重复时识别两行,以便我可以记录两行中的事件#和时间戳:
\\10.xx.xx.x0\c$\PATH\file.log:2017-12-15 07:48:25 Event: UNIQUE EVENT# 12456
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-15 07:48:25 File Read Begin: UNIQUE EVENT# 12456
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-15 07:48:25 WinRead Read: UNIQUE EVENT# 12456
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-15 12:34:20 Event: UNIQUE EVENT# 2467
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-15 12:34:20 File Read Begin: UNIQUE EVENT# 2467
\\10.xx.xx.x0\\c$\PATH\file.log:**2017-12-15 12:34:20 WinRead Read**: UNIQUE EVENT# 2467
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-15 12:34:20 Event: UNIQUE EVENT# 3214
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-15 12:34:20 File Read Begin: UNIQUE EVENT# 3214
\\10.xx.xx.x0\\c$\PATH\file.log:**2017-12-15 12:34:20 WinRead Read**: UNIQUE EVENT# 3214
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-15 12:34:26 Event: UNIQUE EVENT# 6251
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-15 12:34:26 File Read Begin: UNIQUE EVENT# 6251
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-15 12:34:26 WinRead Read: UNIQUE EVENT# 6251
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-16 04:35:29 Event: UNIQUE EVENT# 1547
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-16 04:35:29 File Read Begin: UNIQUE EVENT# 1547
\\10.xx.xx.x0\\c$\PATH\file.log:2017-12-16 04:35:29 WinRead Read: UNIQUE EVENT# 1547
在我被挂断之前,这是我能得到的
findstr /r ....\-..\-.....\:..\:...Event.* file.log > temp.txt
FOR /f "tokens=1 delims=:" %%d IN ('temp.txt') do (FOR /F "tokens=3 delims= " %%g IN ("%%d") DO set STR1=%%g)
答案 0 :(得分:1)
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q48264584.txt"
SET "lastevent="
FOR /f "tokens=1*delims=:" %%a IN ('type "%filename1%"^|findstr /i "winread" ') DO (
FOR /f "tokens=1,3delims=W#" %%d IN ("%%b") DO (
IF "!lastevent!"=="%%d" (
ECHO !lastevent! #!lastunique!
ECHO %%d #%%e
)
SET "lastevent=%%d"
SET "lastunique=%%e"
)
)
GOTO :EOF
您需要更改sourcedir
的设置以适合您的具体情况。
我使用了一个名为q48264584.txt
的文件,其中包含我的测试数据。
使用看似所需的数据,分析显示所需的行在第一个:
和单词winread
之后直接唯一地包含日期戳,因此
读取包含winread
的文件的每一行。使用:
进行标记,以便第一个:
之前的部分转到%%a
(被忽略),并将该行的其余部分转移到%%b
。
然后使用%%b
(终止日期戳)和w
(在所需事件编号之前)的分隔符标记#
。选择令牌1(日期戳)和3(事件编号)分别为%%d
,%%e
。
使用delayed expansion
,将日期戳与lastevent
进行比较,如果相同则我们有重复,所以显示最后一个事件时间和最后一个唯一ID(可能名称应更改为{{ 1}}和lastdatestamp
)及其当前值。
无论如何,保存数据以便下一次迭代与上一个(已过滤)行中找到的值进行比较。
根据时间格式的修改:
lastevent
这里实际改变的是REM <!-- language: lang-dos -->
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q48264584.txt"
SET "lastevent="
FOR /f "tokens=1*delims=:" %%a IN ('type "%filename1%"^|findstr /i "winread" ') DO (
FOR /f "tokens=1,3delims=W#" %%d IN ("%%b") DO (
CALL :comparetimes "%%d"
IF DEFINED sametime (
ECHO !lastevent! #!lastunique!
ECHO %%d #%%e
)
SET "lastevent=%%d"
SET "lastunique=%%e"
)
)
GOTO :EOF
::
:: Compare time in %1 to time in 'lastevent'
::
:comparetimes
SET "sametime="
IF NOT DEFINED lastevent GOTO :eof
SET "event2=%~1"
:: each of 'event2' and 'lastevent' are "date time" + space
:: select simply the time portion, except milliseconds
SET "event1=%lastevent:~-13,8%"
SET "event2=%event2:~-13,8%"
IF "%event1%"=="%event2%" SET "sametime=Y"&GOTO :EOF
:: not same time - try difference 1 second - add 1 sec to event1
:: remove colons and string `1` before each time to convert to integer
:: 1000000 to 1235959; add 1 sec to event1
SET /a event2=1%event2::=%
SET /a event1=1%event1::=%+1
:: if last 2 digits of 'event1' are now "60" time was ??:??:59
:: so add 40 to bump minutes
IF 1%event1:~-2% geq 160 SET /a event1+=40
:: ditto hours...
IF 1%event1:~-4,2% geq 160 SET /a event1+=4000
:: finally days, but this time, event 1 MUST now be '1240000'+
:: so simply subtract 240000
IF %event1% geq 1240000 SET /a event1-=240000
IF %event1% geq %event2% SET "sametime=Y"&GOTO :EOF
GOTO :eof
是由sametime
例程操纵的标志。 :comparetimes
解释变量的运行时值,因此不需要if defined
。
delayedexpansion
例程接受来自主循环的日期/时间输入作为其第一个参数(%1),并将其分配给:comparetimes
(因为它是事件对的第二个)为{ {1}}删除封闭的引号。然后,我们从结尾的event2
字符开始选择两次%~1
字符8
和%1
} - 这将是hh:mm:ss。
如果两次相同,我们可以设置lastevent
标志来报告数据,我们就完成了。否则,时间不一样,买可能相差1秒(... xx:999到... xx + 1:000)所以我们需要处理批量数学 - 其中包括可爱的想法是,以13
开头的数字是八进制因此可能不包含sametime
或0
。执行此操作的常规方法是在字符串之前将8
字符串设置为十进制,因此需要进行奇怪的调整。
请注意,例如9
将转换为1
。当我们向其添加1(秒)时,我们得到12:59:59
,因此我们需要添加100并减去60以生成此1125959
,然后添加10000并减去6000以使其成为1125960
。
我使用1126000
代替1130000
,以便只需更改添加到geq
的数字即可扩展1秒的“窗口”。例如,如果这是5秒,则equ/==
将转换为event1
。当我们向此添加5(秒)时,我们得到12:59:59
,因此我们需要添加100并减去60以生成此1125959
,然后添加10000并减去6000以使其成为1125964
因此,如果1126004
(大于或等于)1130004
{} p>