Reputation: 1
I have a log file like below:
Beginning difffull backup for database Managed_Metadata_Service, 3 of 149.
Full: 0 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 4 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Backup of Managed_Metadata_Service failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Beginning difffull backup for database model, 4 of 149.
Full: 0 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 2 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 4 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Backup of model failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Beginning difffull backup for database msdb, 5 of 149.
Full: 0 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 4 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Backup of msdb failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Beginning difffull backup for database Search_Service_Application_AnalyticsReportingStoreDB, 6 of 149.
Full: 0 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 4 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Backup of Search_Service_Application_AnalyticsReportingStoreDB failed.
ANS0238E (RC2041) The sequence of calls is invalid.
How can I find all occurrences of failed
and then print the line with this word and the next lines until end of message which means until next dot at end of paragraph or end of file?
The result would be like this:
Backup of Managed_Metadata_Service failed.
ANS0238E (RC2041) The sequence of calls is invalid.
.
.
Search_Service_Application_AnalyticsReportingStoreDB failed.
ANS0238E (RC2041) The sequence of calls is invalid.
For all lines with failed
word.
Here is the code I have so far:
@echo off
setlocal EnableDelayedExpansion
set numbers=
for /F "delims=^" %%a in ('findstr /I /N /C:"failed" Backup_DIFF_2017-12-14.log') do (
set /A sameline=%%a, after=%%a+1
set "numbers=!numbers!!sameline!: !after!: "
)
rem Search for the lines
(
for /F "tokens=* delims=^ %%a in ('findstr /N "^" Backup_DIFF_2017-12-14.log ^| findstr /B "%numbers%"') do echo %%b
) > result.txt
Upvotes: 0
Views: 172
Reputation: 49086
The simple solution as suggested by Stephan for this log file example is:
@%SystemRoot%\System32\findstr.exe "failed\.$ ^ANS" "Backup_DIFF_2017-12-14.log"
This single command line outputs:
Backup of Managed_Metadata_Service failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Backup of model failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Backup of msdb failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Backup of Search_Service_Application_AnalyticsReportingStoreDB failed.
ANS0238E (RC2041) The sequence of calls is invalid.
FINDSTR searches for either a line ending with failed.
or a line starting with ANS
and outputs those lines. The dot must be in the regular expression search string with a backslash to be interpreted as literal character. A multi-line regular expression search is not supported by FINDSTR.
Alternate FINDSTR command line also running two regular expression searches on each line OR combined:
@%SystemRoot%\System32\findstr.exe /R /C:failed\.$ /C:^ANS "Backup_DIFF_2017-12-14.log"
A more complex solution is using this batch code:
@echo off
if not exist "Backup_DIFF_2017-12-14.log" goto :EOF
setlocal EnableExtensions EnableDelayedExpansion
set "PrintLines="
for /F "tokens=1* delims=:" %%I in ('%SystemRoot%\System32\findstr.exe /N /R "^" "Backup_DIFF_2017-12-14.log"') do (
if "%%J" == "" (
set "PrintLines="
) else (
set "Line=%%J"
if not "!Line:failed=!" == "!Line!" set "PrintLines=1"
)
if defined PrintLines echo %%J
)
endlocal
The output is the same. This code outputs any line containing anywhere case-insensitive failed
and outputs this line as well as all other lines up to next empty line in file. An empty line does not contain any character, not even a space or horizontal tab character.
There are two issues with this code:
delims=:
required to split up each line output by FINDSTR with line number, colon and line itself.
FINDSTR is used to process by FOR even empty lines because all lines including empty lines start with line number and colon after running FINDSTR on file searching for begin of a line which results in a positive match on every line.set "Line=%%J"
after replacing %%J
by the line from file.Another not 100% perfect solution:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "PrintLines="
for /F "usebackq delims=" %%I in ("Backup_DIFF_2017-12-14.log") do (
set "Line=%%I"
if "!Line:~0,9!" == "Beginning" (
set "PrintLines="
) else (
if not "!Line:failed=!" == "!Line!" set "PrintLines=1"
)
if defined PrintLines echo %%I
)
endlocal
In comparison to second solution this batch code interprets case-sensitive Beginning
at begin of a line as new paragraph instead of an empty line. For that reason the command FOR can process the file directly with ignoring empty lines.
But also this solution has two issues:
;
is the default for option eol
not explicitly set to a different character. This issue can be solved by specifying eol=
with a character which definitely never exists at beginning of a line in the log file.set "Line=%%I"
after replacing %%I
by the line from file.It is expected by this solution that a line starting with Beginning
does not contain the word failed
anywhere in the line.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
findstr /?
for /?
goto /?
if /?
set /?
setlocal /?
Upvotes: 1