如何使用Findstr从一个文件中提取多行文本并输出到另一个文件

时间:2017-05-18 20:35:42

标签: batch-file

我有一个软件正在输出日志文件,而我正在尝试编写一个批处理文件,该文件将提取错误的行并将它们转储到单独的文本文件中。到目前为止,我有一个批处理文件,它将复制第一行,但由于某些错误可能跨越多行而无法正常工作。

我的示例日志文件是Test.txt:

2017-05-18 |Status| <<Everything is working great>>
2017-5-18 |Error| <<Error message here and continues on, sometimes for multiple lines>>
2017-5-18 |Status| <<Things are great again>>

我写的用于解压错误的批处理文件是:

@echo off
setlocal EnableDelayedExpansion
(for /F "tokens=1* delims=:" %%a in ('findstr /N /C:"|Error|" Test.txt') do echo %%b) > output.txt

这有点起作用,因为它会提取包含| Error |的行但是在第一行之后切断的错误消息会更长。我想让它复制输入块,其中包含| Error |一直到&#34;&gt;&gt;&#34;

2 个答案:

答案 0 :(得分:0)

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q44057323.txt"
SET "outfile=%destdir%\outfile.txt"

SET "output="
(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
 SET "errorline="
 SET "chevrons="
 ECHO "%%a"|FIND /i "|error|">NUL
 IF NOT ERRORLEVEL 1 SET "errorline=Y"
 ECHO "%%a"|FIND /i ">>">NUL
 IF NOT ERRORLEVEL 1 SET "chevrons=Y"
 IF DEFINED errorline SET  "output=Y"
 IF DEFINED output ECHO %%a
 IF DEFINED chevrons SET "output="
)
)>"%outfile%"

GOTO :EOF

您需要更改sourcedirdestdir的设置以适合您的具体情况。

我使用了一个名为q44057323.txt的文件,其中包含我的测试数据。

生成定义为%outfile%

的文件

如果你包含一个多行错误的例子会更好。事实上,我们被迫得出结论:>>标志着消息的结束,并且这只出现在消息的末尾。

读取每一行,检测目标字符串的存在并根据需要设置开关。如果检测到第一个字符串,请转动开启输出,如果找到第二个字符串,请转动关闭输出。

答案 1 :(得分:0)

以下代码完成了您想要的任务:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

rem // Define constants here:
set "_FILE=.\Test.txt"
set "_RETURN=.\output.txt" & if not defined _RETURN set "_RETURN=con"
set "_BEGIN=|Error| <<" & rem // (case-insensitive search string)
set "_END=>>"           & rem // (case-insensitive search string)

rem // Count number of lines:
for /F %%C in ('^< "!_FILE!" find /C /V ""') do (
    rem // Reset flag:
    set "FLAG="
    rem // Read and write files by redirection:
    < "!_FILE!" > "!_RETURN!" (
        rem // Loop through all lines:
        for /L %%I in (1,1,%%C) do (
            rem // Read a single line:
            set "LINE=" & set /P LINE=""
            rem // Set flag if line contains search string a block begins with:
            if not "!LINE!"=="!LINE:%_BEGIN%=!" set "FLAG=#"
            rem // Return current line only in case flag is set:
            if defined FLAG echo(!LINE!
            rem // Reset flag if line contains search string a block ends with:
            if not "!LINE!"=="!LINE:%_END%=!" set "FLAG="
        )
    )
)

endlocal
exit /B

请注意,如果文件包含超过2147483647行和/或任何行包含超过1023个字符/字节,则会失败。