批处理脚本以提取指定单词之间的行

时间:2014-08-19 18:31:16

标签: batch-file scripting extract lines

我有一个如下所示的日志文件。

  

[Tue Aug 19 10:45:28 2014] Local / PLPLAN / PL / giuraja @ MSAD / 2172 / Info(1019025)

     

从数据库的规则对象读取规则[PL]

     

[Tue Aug 19 10:45:28 2014] Local / PLPLAN / PL / giuraja @ MSAD / 2172 / Info(1013157)

     

使用[AIF0142.rul]用数据文件[SQL]

从用户[giuraja @ MSAD]收到命令[导入]      

     

     

     

     

     

清除活动用户[giuraja @ MSAD]实例[1]

     

     

我想提取以“[Tue Aug 19 10:”开头的行,直到以“Clear Active on User”开头的行,并使用Windows批处理脚本输出到文件。我尝试了下面的代码。它只输出最后一行。

  

@echo off& setlocal enabledelayedexpansion

     

设置Month_Num =%date:~4,2%

     

如果%Month_Num%== 08设置Month_Name = Aug

     

设置Day =%date:~0.3%

     

设置Today_Date =%date:~7,2%

     

设置Search_String = [%Day %% Month_Name %% Today_Date%10:

     

for / f“tokens = 1 delims = []”%% a in('find / n“%Search_String%”^      

@(

     

more + %% a D:\ Hyperion \ ERPI_Actuals_Load \ Logs \ PLPLAN.LOG)> D:\ Hyperion \ ERPI_Actuals_Load \ Logs \ PLPLAN_Temp.txt

     

(对于/ f“tokens = *”%% a in(D:\ Hyperion \ ERPI_Actuals_Load \ Logs \ PLPLAN_Temp.txt)do(

     

设置test = %% a

     

如果“!test:~0,20!” equ“在用户上清除活动”转到:eof

     

echo %% a

     

))GT; d:\海波\ ERPI_Actuals_Load \日志\ PLPLAN_Formatted.txt

此致 Ragav。

4 个答案:

答案 0 :(得分:2)

下面的批处理文件旨在尽可能快地处理大文件;但是,它会从结果中删除空行:

@echo off
setlocal EnableDelayedExpansion

set "start=[Tue Aug 19 10:"
set "end=Clear Active on User"

for /F %%a in ("%start%") do set startWord=%%a
for /F %%a in ("%end%") do set endWord=%%a

set "startLine="
set "endLine="
for /F "tokens=1,2 delims=: " %%a in ('findstr /I /N /B /C:"%start%" /C:"%end%" logFile.txt') do (
   if not defined startLine if "%%b" equ "%startWord%" set startLine=%%a
   if not defined endLine if "%%b" equ "%endWord%" set "endLine=%%a" & goto continue0
)
:continue0
set /A skipLines=startLine-1, numLines=endLine-startLine+1
set "skip="
if %skipLines% gtr 0 set skip=skip=%skipLines%

(for /F "%skip% delims=" %%a in (logFile.txt) do (
   echo %%a
   set /A numLines-=1
   if !numLines! equ 0 goto continue1
)) > outFile1.txt
:continue1

rem Previous outFile1.txt contain as many extra lines as empty lines removed, so we need to eliminate they

for /F "delims=:" %%a in ('findstr /I /N /B /C:"%end%" outFile1.txt') do set numLines=%%a
(for /F "delims=" %%a in (outFile1.txt) do (
   echo %%a
   set /A numLines-=1
   if !numLines! equ 0 goto continue2
)) > outFile2.txt
:continue2

del outFile1.txt
TYPE outFile2.txt

如果您想保留空行,则该过程将更慢。

答案 1 :(得分:1)

这是一个包含(开始和结束行显示)脚本应该完成这项工作。您可以修改它以排除行:

@echo off
setlocal

set filename=text_file.txt
for /f "tokens=1 delims=:"  %%a in ('findstr /n /b /c:"[Tue Aug " %filename%') do (
    set /a f_line=%%a-1
)

for /f "tokens=1 delims=:"  %%a in ('findstr /n /b /c:"Clear Active on User" %filename%') do (
    set /a l_line=%%a
)
 echo %l_line% -- %f_line%

call :tail_head2 -file=%filename% -begin=%f_line%  -end=%l_line% 


exit /b 0




@echo off
:tail_head2
setlocal


rem ---------------------------
rem ------ arg parsing --------
rem ---------------------------

    if "%~1" equ "" goto :help
        for %%H in (/h -h /help -help) do (
                if /I "%~1" equ "%%H" goto :help
        )
        setlocal enableDelayedExpansion
            set "prev="
            for %%A in (%*) do (
                    if /I "!prev!" equ "-file" set file=%%~fsA
                    if /I "!prev!" equ "-begin" set begin=%%~A
                    if /I "!prev!" equ "-end" set end=%%A
                    set prev=%%~A
            )
        endlocal & (
                if "%file%" neq "" (set file=%file%)
                if "%begin%" neq "" (set /a begin=%begin%)
                if "%end%" neq "" (set /a end=%end%)
        )

rem -----------------------------
rem --- invalid cases check -----
rem -----------------------------

        if "%file%" EQU "" echo file not defined && exit /b 1
        if not exist "%file%"  echo file not exists && exit /b 2
        if not defined begin if not defined end echo neither BEGIN line nor END line are defined && exit /b 3

rem --------------------------
rem -- function selection ----
rem --------------------------

        if defined begin if %begin%0 LSS 0 for /F %%C in ('find /c /v "" ^<"%file%"')  do set /a lines_count=%%C
        if defined end if %end%0 LSS 0 if not defined lines_count for /F %%C in ('find /c /v "" ^<"%file%"')  do set lines_count=%%C

                rem -- begin only
        if not defined begin if defined end if %end%0 GEQ 0 goto :end_only
        if not defined begin if defined end if %end%0 LSS 0 (
                        set /a end=%lines_count%%end%+1
                        goto :end_only
                )

                rem -- end only
        if not defined end if defined begin if %begin%0 GEQ 0 goto :begin_only
        if not defined end if defined begin if %begin%0 LSS 0 (
                        set /a begin=%lines_count%%begin%+1
                        goto :begin_only
                )
                rem -- begin and end
        if %begin%0 LSS 0 if %end%0 LSS 0 (
                        set /a begin=%lines_count%%begin%+1
                        set /a end=%lines_count%%end%+1
                        goto :begin_end
                )
        if %begin%0 LSS 0 if %end%0 GEQ 0 (
                        set /a begin=%lines_count%%begin%+1
                        goto :begin_end
                )
        if %begin%0 GEQ 0 if %end%0 LSS 0 (
                        set /a end=%lines_count%%end%+1
                        goto :begin_end
                )
        if %begin%0 GEQ 0 if %end%0 GEQ 0 (
                        goto :begin_end
                )      
goto :eof

rem -------------------------
rem ------ functions --------
rem -------------------------

rem -----  single cases -----

:begin_only
        setlocal DisableDelayedExpansion
        for /F "delims=" %%L in ('findstr /R /N "^" "%file%"') do (
                set "line=%%L"
                for /F "delims=:" %%n in ("%%L") do (
                        if %%n GEQ %begin% (
                                setlocal EnableDelayedExpansion
                                set "text=!line:*:=!"
                                (echo(!text!)
                                endlocal
                        )
                )
        )
        endlocal
endlocal
goto :eof

:end_only
        setlocal disableDelayedExpansion
        for /F "delims=" %%L in ('findstr /R /N "^" "%file%"') do (
                set "line=%%L"
                for /F "delims=:" %%n in ("%%L") do (
                        IF %%n LEQ %end% (
                                setlocal EnableDelayedExpansion
                                set "text=!line:*:=!"
                                (echo(!text!)
                                endlocal
                        ) ELSE goto :break_eo
                )
        )
        :break_eo
        endlocal
endlocal
goto :eof

rem ---  end and begin case  -----

:begin_end
        setlocal disableDelayedExpansion
        if %begin% GTR %end% goto :break_be
        for /F "delims=" %%L in ('findstr /R /N "^" "%file%"') do (
                set "line=%%L"
                for /F "delims=:" %%n in ("%%L") do (
                    IF %%n GEQ %begin% IF %%n LEQ %end% (        
                        setlocal EnableDelayedExpansion
                        set "text=!line:*:=!"
                       (echo(!text!)
                        endlocal
                    ) ELSE goto :break_be                              
                )
        )
        :break_be
        endlocal
endlocal
goto :eof
rem ------------------
rem --- HELP ---------
rem ------------------
:help
    echo(
        echo %~n0 - dipsplays a lines of a file defined by -BEGIN and -END arguments passed to it
        echo(
        echo( USAGE:
        echo(
        echo %~n0  -file=file_to_process {-begin=begin_line ^| -end=end_line }
        echo or
        echo %~n0  -file file_to_process {-begin begin_line ^| -end end_line }
        echo(
        echo( if some of arguments BEGIN or END has a negative number it will start to count from the end of file
        echo(
        echo( http://ss64.org/viewtopic.php^?id^=1707
        echo(
goto :eof

编辑 - 最后100行:

@echo off
setlocal

set filename=text_file.txt
for /F %%C in ('find /c /v "" ^<"%filename%"')  do set /a lines_count=%%C
set /a last_100_lines=lines_count-100

type %filename% | more /e +%last_100_lines%

答案 2 :(得分:1)

这应该有效(测试)

@echo off
set "st_line=Tue Aug 19"
set "end_line=Clear Active on User"
for /f "delims=:" %%i in ('findstr /inc:"%st_line%" logfile.txt') do (set st_line_ln=%%i)
for /f "delims=:" %%j in ('findstr /inc:"%end_line%" logfile.txt') do (set end_line_ln=%%j)

findstr /in /c:[a-z] /c:[0-9] /rc:"^$" logfile.txt >logfile_ln.txt

set /a "st_line_ln_temp=%st_line_ln-1"

for /f "skip=%st_line_ln_temp% tokens=1* delims=:" %%a in ('type logfile_ln.txt') do (
 if %%a leq %end_line_ln% (echo.%%b) 
)

del logfile_ln.txt

示例输出 -

C:\test>type logfile.txt
Tue Aug 19 10:45:28 2014]Local/PLPLAN/PL/giuraja@MSAD/2172/Info(1019025)

Reading Rules From Rule Object For Database [PL]

[Tue Aug 19 10:45:28 2014]Local/PLPLAN/PL/giuraja@MSAD/2172/Info(1013157)

Received Command [Import] from user [giuraja@MSAD] using [AIF0142.rul] with data file [SQL]

test1
test2
test4
test546
Clear Active on User [giuraja@MSAD] Instance [1
test1212
test232
test67
dj

C:\test>draft.bat
[Tue Aug 19 10:45:28 2014]Local/PLPLAN/PL/giuraja@MSAD/2172/Info(1013157)

Received Command [Import] from user [giuraja@MSAD] using [AIF0142.rul] with data file [SQL]

test1
test2
test4
test546
Clear Active on User [giuraja@MSAD] Instance [1
C:\test>

干杯,G

答案 3 :(得分:1)

@ECHO OFF
SETLOCAL
:: If you don't want to preserve empty lines
SET "select="
(
 FOR /f "delims=" %%a IN (q25390541.txt) DO (
  ECHO %%a|FINDSTR /b /L /c:"[Tue Aug 19 10:" >NUL
  IF NOT ERRORLEVEL 1 SET select=y
  IF DEFINED select ECHO(%%a
  ECHO %%a|FINDSTR /b /L /c:"Clear Active on User" >NUL
  IF NOT ERRORLEVEL 1 GOTO done1
 )
)>newfile.txt

:done1

:: If you want to preserve empty lines
SET "select="
(
 FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r ".*" q25390541.txt') DO (
  IF "%%b"=="" (
   IF DEFINED select ECHO(
  ) ELSE (
   ECHO %%b|FINDSTR /b /L /c:"[Tue Aug 19 10:" >NUL
   IF NOT ERRORLEVEL 1 SET select=Y
   IF DEFINED select ECHO(%%b
   ECHO %%b|FINDSTR /b /L /c:"Clear Active on User" >NUL
   IF NOT ERRORLEVEL 1 GOTO done2
  )
 )
)>newfile2.txt

:done2

GOTO :EOF

我使用了一个名为q25390541.txt的文件,其中包含我的测试数据。 生成newfile.txtnewfile2.txt,具体取决于哪个。