删除之前的1行,匹配后的1行以及匹配

时间:2018-04-04 09:08:04

标签: batch-file cmd

我需要编辑一个大尺寸(> 300mb)的日志文件删除行。 要删除的行是字符串匹配的行,前一行和后一行。 我必须在windows中运行这个bat / cmd。

我的MASTER.log示例:

[Thu May 11 16:39:58 2017]Local/MASTER///9044/Info(1042059)
Connected from [::ffff:10.64.44.209]

[Thu May 11 16:39:58 2017]Local/MASTER/Plan2/admin@Native Directory/9044/Info(1204002)
Hybrid Aggregation Mode enabled.

[Thu May 11 16:39:58 2017]Local/MASTER/Plan2/admin@Native Directory/9044/Info(1013091)
Received Command [MdxReport] from user [admin@Native Directory]

[Thu May 11 16:39:58 2017]Local/MASTER/Plan2/admin@Native Directory/9044/Info(1204002)
Hybrid Aggregation Mode enabled.

[Thu May 11 16:39:58 2017]Local/MASTER/Plan2/admin@Native Directory/9044/Info(1204002)
Hybrid Aggregation Mode enabled.

[Thu May 11 16:39:58 2017]Local/MASTER/Plan2/admin@Native Directory/9044/Info(1260039)
MaxL DML Execution Elapsed Time : [0.019] seconds

我需要搜索"启用混合聚合模式的每一次重现"并删除匹配行,前一行和后一行。

结果应为:

[Thu May 11 16:39:58 2017]Local/MASTER///9044/Info(1042059)
Connected from [::ffff:10.64.44.209]

[Thu May 11 16:39:58 2017]Local/MASTER/Plan2/admin@Native Directory/9044/Info(1013091)
Received Command [MdxReport] from user [admin@Native Directory]

[Thu May 11 16:39:58 2017]Local/MASTER/Plan2/admin@Native Directory/9044/Info(1260039)
MaxL DML Execution Elapsed Time : [0.019] seconds

我尝试使用findstr,但我只能删除结果行。

1 个答案:

答案 0 :(得分:0)

虽然你没有表现出任何自己的努力来解决你的任务,但我决定提供一个小脚本,因为它看起来很有趣;查看代码中的所有解释性说明(下次请分享您的努力并准确描述您遇到的问题;请参阅tour):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE=%~1" & rem // (path/name of file to process; use first command line argument)
set "_STR=Hybrid Aggregation Mode enabled." & rem // (string to search for)
set /A "_NUM=3" & rem // (count of lines to remove; begin counting at line before match)

rem // Initialise variables:
set /A "SKIP=1"
rem // Read file, iterate over all lines plus one, not ignoring empty lines:
for /F "delims=" %%L in ('findstr /N /R "^" "%_FILE%" ^& echo :') do (
    rem // Store current line string:
    set "LINE=%%L"
    setlocal EnableDelayedExpansion
    rem // Check whether current line string constitutes a match:
    set "COMP=!LINE:*:=!"
    if "!COMP!"=="!_STR!" (
        endlocal
        rem // Match encountered, hence set line skip counter:
        set /A "SKIP=_NUM"
        setlocal EnableDelayedExpansion
    )
    rem // Check whether line skip counter reached zero:
    if !SKIP! gtr 0 (
        endlocal
        rem // Zero not reached, so decrement line skip counter:
        set /A "SKIP-=1"
        setlocal EnableDelayedExpansion
    ) else (
        rem // Zero reached, so return previous line string:
        echo(!PREV!
    )
    rem // Store current line string for next loop iteration:
    for /F "delims=" %%E in (^""!LINE:*:=!"^") do (
        endlocal
        set "PREV=%%~E"
    )
)

endlocal
exit /B

我假设您希望整行以区分大小写的方式匹配搜索字符串。如果您想要不同的行为,则必须相应地交换行if "!COMP!"=="!_STR!" (

  • 要匹配案例中的整行 - 敏感方式,请使用:

    if /I "!COMP!"=="!_STR!" (
    
  • 对于包含< - strong> 敏感方式的搜索字符串的行,请使用:

    if defined COMP if not "!COMP!"=="!COMP:%_STR%=!" (
    

    在这种情况下,搜索字符串_STR不能为空,不得包含=!"^,且不得开头使用*~

  • 对于以区分大小写的方式包含搜索字符串的行,请使用:

    if defined COMP if not "!COMP!"=="!COMP:%_STR%=!" if "!COMP!"=="!COMP:%_STR%=%_STR%!" (
    

    在这种情况下,适用与前一项相同的限制。

要使用脚本 - 让我们称之为mitigate.bat - 提供输入日志文件作为命令行参数,如下所示:

mitigate.bat "MASTER.log"

要将脚本的输出写入文件,请键入以下内容(请注意输入和输出文件必须不同):

mitigate.bat "MASTER.log" > "MASTER_mod.log"