如果重复动态字符串,则批处理返回行

时间:2018-01-15 14:02:55

标签: batch-file cmd find

如果重复一个字符串,试图找出一种方法让批处理从日志文件返回一行。该字符串包含时间戳,因此字符串会更改。

我做了一个示例日志。 我希望在同一秒内在时间戳字符串重复时识别两行,以便我可以记录两行中的事件#和时间戳:

\\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) 

1 个答案:

答案 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开头的数字是八进制因此可能不包含sametime0。执行此操作的常规方法是在字符串之前将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

相关问题